Pada Apa Saya Harus Memecah atau Memartisi Meja yang Sangat Besar tapi Sederhana

8

Situs kami memiliki beberapa tabel besar tapi sederhana (INT, INT, DATE) untuk statistik. Setiap meja memiliki hingga 300.000.000 baris, dan bertambah besar setiap hari.

Penyedia hosting telah menyarankan agar kami membagi atau mempartisi tabel, dan saya telah melihat rekomendasi ini di tempat lain pada banyak kesempatan.

Namun...

Saya berjuang untuk mencocokkan saran ini dengan kapasitas maksimum yang dinyatakan untuk SQL Server - ukuran basis data 524.272 terabyte, dengan baris tabel hanya dibatasi oleh "penyimpanan yang tersedia".

Berdasarkan angka-angka itu, tabel yang diuraikan di atas dapat dengan mudah memiliki jutaan baris (10 pangkat 303).

Ah ha Anda mungkin berkata, ada perbedaan antara KAPABILITAS dan KINERJA.

Tetapi dalam hampir setiap pertanyaan tentang kinerja SQL Server jawabannya adalah "Itu tergantung .... pada desain tabel dan desain permintaan".

Itu sebabnya saya menanyakan pertanyaan ini. Desain meja tidak bisa lebih sederhana. Kueri juga bukan operasi penghitungan sederhana (*) berdasarkan bidang ID yang diindeks.

Martin Hansen Lennox
sumber
Tabel partisi adalah sesuatu yang Anda rencanakan dalam desain basis data Anda, sebelum benar-benar menulis data. Jauh lebih sulit dan melelahkan untuk melakukan ini setelah fakta.
1
Itu lebih tergantung pada skenario Anda: apakah kinerja baik-baik saja? Bisakah Anda mengarsipkan beberapa data? Apakah tabel sebesar ini masuk akal untuk dicadangkan / dipulihkan secara efisien? Apakah mereka dikompres? Akan baik untuk dipartisi dari hari pertama, tetapi hari terbaik berikutnya adalah hari ini jika Anda khawatir tentang kinerja masa depan jika Anda ingin mengikuti praktik terbaik.
LowlyDBA
2
Saya pikir dengan jumlah data ini Anda akan perlu untuk membagi database Anda pada tingkat arsitektur, database OLTP dan database OLAP, database aplikasi Anda "OLTP" seharusnya hanya menyimpan data minimum yang diperlukan untuk aplikasi dan bisnis, sisanya harus dibuang ke dalam data gudang "OLAP". Sejauh pertanyaannya adalah ketika Anda harus mulai mempartisi tabel Anda lihat artikel ini oleh Kendra LittleHow To Decide if You Should Use Table Partitioning
M.Ali
3
Kinerja tidak pernah menjadi kenyataan bahwa sebuah meja besar. Kenyataannya apa yang besar bagi banyak orang kecil bagi sebagian orang. Memahami operasi apa yang dibuat lebih cepat dan yang lebih lambat dengan mempartisi. Partisi bukan saklar yang lebih cepat. Ini adalah saklar yang lebih lambat dan beberapa hal menjadi sangat cepat.
usr
4
Saya sangat merekomendasikan video pelatihan MCM tentang pemartisian oleh Kimberly Tripp.
Paul White 9

Jawaban:

10

Ada alasan bahwa saran umum adalah bahwa itu tergantung pada desain tabel dan pertanyaan di atasnya. Jawaban saya untuk posting Anda yang lain di Stack Exchange juga mengatakan begitu. Mengatakan "kueri yang merupakan penghitungan sederhana (*) operasi berdasarkan bidang ID yang diindeks" tidak memberikan banyak informasi karena tidak mengatakan kardinalitas dari rangkaian baris yang dipertimbangkan. Hal yang dapat Anda lakukan untuk mengurangi masalah (seperti yang sekarang dirasakan) adalah:

  1. Partisi. Secara khusus, data Anda tampaknya merupakan tipe data pencatatan. Dugaan saya adalah bahwa Anda ingin mendapatkan statistik berdasarkan beberapa satuan waktu (mis. "Widget per hari" atau "whozits per jam"). Partisi dengan kuantum Anda (yaitu hari atau jam dalam contoh sebelumnya) dan pindahkan partisi ke grup file hanya-baca sesekali

  2. Pada catatan terkait, jika data ditulis-sekali, pertimbangkan untuk melakukan agregasi data setelah periode waktu tidak lagi aktif. Artinya, mengapa saya harus terus menghitung berapa banyak peristiwa yang terjadi pada hari dari tiga tahun yang lalu jika data itu tidak akan pernah berubah? Setelah hari itu berakhir, hitung semuanya di hari itu, simpan di tempat lain, dan jangan pernah hitung lagi. Bahkan, jika Anda tidak pernah membutuhkan data terperinci (yaitu Anda hanya pernah melakukan agregasi terhadapnya), pertimbangkan untuk menghapusnya setelah Anda menghitungnya. Jika Anda menerapkan ide ini, Anda bisa menjadi lebih pintar dengan indeks yang difilter yang hanya mencakup periode "aktif" yang akan membuat pertanyaan Anda lebih cepat karena mereka tidak akan mencakup sebagian besar data Anda

Tapi, seperti saran saya di posting lain menyarankan, satu-satunya cara Anda akan tahu pasti adalah memuatnya dengan jumlah data yang masuk akal dan mencobanya. Yang bisa kita lakukan di sini adalah mengatakan apa yang mungkin akan berhasil dalam kasus umum. Tanpa spesifikasi perangkat keras, data, dan kueri Anda, yang bisa kami lakukan hanyalah menebak. Dan, Anda mungkin menemukan bahwa sekali Anda menjalankan tes yang saya usulkan bahwa jawabannya adalah "tidak ada yang bisa dilakukan" karena itu berfungsi dengan baik seperti apa adanya.

Ben Thul
sumber
Ben terima kasih. Saya mulai menghargai bahwa ada lebih banyak variabel yang dimainkan daripada yang saya pikirkan. Dan saya menerima bahwa, secara praktis, 'coba dan lihat' adalah pendekatan yang paling masuk akal. Tetapi karena SQL Server pada dasarnya adalah sebuah program (walaupun sangat rumit) bagian dari saya merasa frustrasi dengan kurangnya prediktabilitas ini.
Martin Hansen Lennox
1
@MartinHansenLennox dan Ben: Saya pasti setuju dengan pendekatan "coba saja" sebagai lawan dari hanya mendengarkan saran atau spekulasi pribadi. Tetapi, saya akan merekomendasikan untuk menyatakan secara lebih eksplisit dalam paragraf itu apa artinya benar - benar mencobanya. Ini lebih dari sekedar memuat dan menjalankan kueri. Pengujian harus mencakup penambahan data secara bertahap untuk melihat apakah / bagaimana hal-hal berubah ketika statistik berubah dan indeks terfragmentasi, dll. Dan cobalah mencadangkan, memulihkan, membangun kembali indeks, dll. Perlu dicatat bahwa indeks yang dipartisi, mulai tahun 2012, tidak lagi dapatkan pembaruan status penuh saat membangun kembali.
Solomon Rutzky
@MartinHansenLennox: Anda benar-benar frustrasi dengan pendekatan "coba dan lihat". SQL Server sangat mudah ditebak dan setidaknya secara teori dimungkinkan untuk menganalisis masalah sebelum mencobanya. Namun, jumlah latar belakang pengetahuan yang diperlukan untuk melakukannya sering membuat ini sulit.
Thomas Kejser
7

Saya akan mengambil pendekatan yang berbeda dan perhatikan bahwa mempartisi ( dalam SQL Server ) terutama merupakan fitur manajemen data dengan kinerja kueri menjadi hasil sekunder yang mungkin , tergantung pada bagaimana Anda mengelolanya . 1

Seperti disebutkan dalam artikel yang ditautkan, manfaat utama dari mempartisi adalah Anda dapat dengan cepat memindahkan data dengan menggunakan pengalihan partisi . Misalnya, Anda dapat mengarsipkan data "dingin" ke penyimpanan yang lebih lambat dan menyimpan data "panas" di penyimpanan cepat. Pada interval yang dijadwalkan secara teratur, Anda dapat dengan cepat mengarsipkan data dengan menggulungnya ke arsip tanpa harus melalui proses menunggu ETL untuk melakukan transfer. Namun, seperti yang disebutkan dalam salah satu komentar awal untuk pertanyaan Anda, ini akan membutuhkan pemikiran dan perencanaan yang matang sebelumnya menerapkannya. Juga, tergantung pada edisi SQL Server yang Anda gunakan (Perusahaan), Anda dapat memanfaatkan kompresi data untuk mengompresi setiap partisi.

Sejauh menyangkut kinerja, Anda dapat mengubah eskalasi kunci menjadi AUTO(standarnya adalah TABLE) seperti :

ALTER TABLE dbo.T1 SET (LOCK_ESCALATION = AUTO);
GO

Selain itu, Anda mungkin mendapatkan penghapusan partisi tetapi pola kueri Anda harus sesuai dengan pola yang sangat spesifik dan berulang di dalam sistem Anda - kunci partisi dan kunci clustering dan setiap kunci unik menjadi saling terkait dan sangat penting . Jika saldo ini tidak diperlakukan diakui dan dirancang, Anda berakhir dengan mimpi buruk kinerja.

Dengan munculnya SQL Server 2014, Anda juga dapat memanfaatkan statistik inkremental yang sangat berguna jika Anda secara proaktif memantau dan memperbarui / membuat statitika pada tabel besar.

Jadi, pada titik apa sebuah tabel harus dipartisi? Itu tergantung pada beban kerja kueri Anda, profil data Anda, tetapi yang paling penting, itu tergantung pada fitur manajemen mana dari partisi yang harus Anda manfaatkan. Partisi bukan untuk kinerja kueri, ini terutama untuk manajemen dan administrasi data.

swasheck
sumber
2
"Partisi bukan untuk kinerja permintaan, ini terutama untuk manajemen dan administrasi data" - tampaknya jelas ketika Anda mengatakannya, tapi saya belum pernah mendapatkannya sebelumnya. Link bagus btw, terima kasih
Martin Hansen Lennox
Terima kasih telah menyebutkan bahwa fitur ini terutama untuk manajemen dan bukan kinerja. Saya jarang melihat hal itu disebutkan dan itu cukup membuat frustrasi.
Solomon Rutzky
1
@ MartinHansenLennox: Ada banyak kegunaan untuk mempartisi. Misalnya, jika Anda menggunakan trik partisi hash dan untuk nilai yang memiliki kardinalitas rendah.
Thomas Kejser
7

Sebelum memutuskan seberapa besar Anda menginginkan partisi, harap pertimbangkan implikasi rencana kueri dari partisi. Dari perspektif kinerja murni, partisi berfungsi sebagai bentuk indeks berbutir kasar. Ini dapat memberikan kinerja ekstra, tetapi juga merupakan sumber regresi kinerja, terutama jika kunci partisi tidak muncul di semua kueri. Dari sini, saya mengasumsikan Anda sudah melakukan pekerjaan rumah ini (seperti yang terlihat sudah Anda lakukan).

Aturan praktis yang baik untuk seberapa besar ukuran partisi yang Anda inginkan adalah: Sekitar setengah ukuran DRAM yang Anda miliki di kotak. Alasan untuk rekomendasi ini adalah:

  1. Anda dapat membangun kembali indeks pada partisi tanpa menumpahkannya tempdb. ini JAUH lebih cepat daripada jika Anda menggunakan akses disk (bahkan dengan SSD).
  2. Saat Anda melakukan pembangunan kembali ini, Anda masih bisa memegang seluruh partisi (biasanya yang terbaru) di DRAM untuk menjaga agar kinerja kueri Anda berjalan lamban.

Dengan kata lain, Anda ingin memiliki DRAM yang cukup untuk menampung dua partisi dan ukuran partisi yang Anda inginkan tergantung pada mesin yang Anda jalankan. Mesin yang lebih besar dapat dengan nyaman menangani partisi yang lebih besar.

Perhatikan bahwa panduan ini juga menyediakan ukuran minimum untuk tempdb: Setidaknya ukuran partisi terbesar Anda (sehingga Anda BISA menumpahkan indeks membangun di sana jika tidak ada cukup DRAM ketika Anda membangun kembali indeks).

Anda dapat mempertimbangkan ukuran partisi yang lebih kecil dari ini, tetapi jika Anda melakukannya, ini biasanya ditujukan untuk optimasi kinerja dan bukan untuk mendukung pengelolaan data.

Ada banyak trik lain yang bisa Anda mainkan dengan partisi. Misalnya, mengompresi, agregasi atau menggunakan Fill Factor 100 pada partisi yang hanya dibaca. Tetapi prinsip dasarnya masih adalah: Cobalah untuk menjaga setiap potongan data yang Anda kelola lebih kecil dari DRAM.

PS: Senang melihat Anda tidak mengambil "itu tergantung" sebagai jawaban, selalu meminta metode untuk mendapatkan jawaban.

Thomas Kejser
sumber
Terima kasih Thomas, saran yang bagus, terutama menghargai penjelasan tentang ukuran partisi.
Martin Hansen Lennox
7

Tabel Partisi, seperti beberapa fitur lainnya, cukup sering (atau bahkan mungkin paling sering?) Digunakan secara tidak tepat. Salah satu peringatan yang akan saya berikan telah dinyatakan dengan baik dalam jawaban @ swasheck .

Selain itu, alternatif untuk dipertimbangkan adalah Tampilan yang Dipartisi. Ini adalah cara menjaga tabel yang terpisah sepenuhnya tetapi menghubungkannya bersama-sama melalui UNION ALL dalam Tampilan. Setiap tabel membutuhkan CHECK CONSTRAINT yang menetapkan rentang data yang dimiliki setiap tabel. Pengoptimal mengetahui konstruk ini dan hanya boleh mengakses tabel dasar yang diperlukan oleh kueri menggunakan View (Saya tidak ingat semua persyaratan untuk memiliki pekerjaan ini sebagaimana dimaksud, jadi silakan lihat tautan CREATE VIEW di bagian bawah, tetapi Saya telah mengaturnya sebelumnya dan tidak sulit untuk membuatnya berfungsi seperti yang diharapkan).

Pasti ada beberapa batasan, dan kelemahan utama adalah bahwa itu kurang transparan dibandingkan dengan Tabel Partisi. Namun, manfaat utama adalah bahwa ini adalah tabel yang terpisah, dan karenanya statistik sepenuhnya terpisah, sedangkan dengan Tabel yang Dipartisi mereka adalah untuk seluruh tabel (bahkan jika, mulai di SQL Server 2014, Anda dapat memperbarui statistik per partisi).

Jika Anda tidak akan menggunakan switching partisi masuk dan keluar, Anda harus mempertimbangkan opsi ini. Terutama jika data yang lebih lama tidak banyak berubah karena tabel yang menyimpan data yang lebih lama tidak perlu indeks / statistik mereka diperbarui sesering mungkin (atau mungkin jika data itu tidak pernah berubah).

Kelemahan lain dari Tabel Partisi yang terlalu sering disebut / tidak diketahui adalah mulai di SQL Server 2012, Anda tidak lagi mendapatkan STATISTIK PEMBARUAN "gratis" DENGAN FULLSCAN saat membangun kembali indeks yang dipartisi. Anda masih mendapatkan statistik pembaruan ini dengan membangun kembali pada indeks non-dipartisi, yang indeks pada tabel dalam Tampilan Partisi akan :).

Untuk informasi lebih lanjut tentang Tampilan yang Dipartisi, silakan periksa halaman MSDN untuk CREATE VIEW dan cari bagian tentang "Tampilan yang Dipartisi" di bawah "Keterangan".

Solomon Rutzky
sumber
2
Poin bagus di STATISTIK PEMBARUAN. Tampilan yang diindeks mengatasi banyak masalah partisi jika Anda dapat menangani dampak pengoptimal.
Thomas Kejser