Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Mempartisi dengan Anggaran

Tahun lalu, saya menyajikan solusi untuk mensimulasikan sekunder yang dapat dibaca Availability Group tanpa berinvestasi di Edisi Perusahaan. Bukan untuk menghentikan orang membeli Edisi Perusahaan, karena ada banyak manfaat di luar AG, tetapi lebih dari itu bagi mereka yang tidak memiliki kesempatan untuk memiliki Edisi Perusahaan sejak awal:

  • Sekunder yang Dapat Dibaca dengan Anggaran terbatas

Saya mencoba menjadi advokat tanpa henti untuk pelanggan Edisi Standar; itu hampir merupakan lelucon yang pasti – mengingat jumlah fitur yang didapatnya di setiap rilis baru – edisi itu secara keseluruhan berada di jalur penghentian. Dalam rapat pribadi dengan Microsoft, saya telah mendorong agar fitur-fitur juga disertakan dalam Edisi Standar, terutama dengan fitur-fitur yang jauh lebih bermanfaat bagi bisnis kecil daripada bisnis dengan anggaran perangkat keras yang tidak terbatas.

Pelanggan Edisi Perusahaan menikmati manfaat pengelolaan dan kinerja yang ditawarkan oleh partisi tabel, tetapi fitur ini tidak tersedia di Edisi Standar. Sebuah ide baru-baru ini mengejutkan saya bahwa ada cara untuk mencapai setidaknya beberapa keuntungan partisi pada edisi apa pun, dan itu tidak melibatkan tampilan yang dipartisi. Ini bukan untuk mengatakan bahwa tampilan yang dipartisi bukanlah pilihan yang layak untuk dipertimbangkan; ini dijelaskan dengan baik oleh orang lain, termasuk Daniel Hutmacher (Pandangan yang dipartisi atas partisi tabel) dan Kimberly Tripp (Tabel yang Dipartisi v. Tampilan yang Dipartisi–Mengapa mereka masih ada?). Ide saya hanya sedikit lebih sederhana untuk diterapkan.

Pahlawan Baru Anda:Indeks yang Difilter

Sekarang, saya tahu, fitur ini adalah kata empat huruf bagi beberapa orang; sebelum Anda melangkah lebih jauh, Anda harus merasa nyaman dengan indeks yang difilter, atau setidaknya menyadari keterbatasannya. Beberapa bacaan untuk memberi Anda keseimbangan yang adil sebelum saya mencoba menjualnya kepada Anda:

  • Saya berbicara tentang beberapa kekurangan di Bagaimana indeks yang difilter bisa menjadi fitur yang lebih kuat, dan menunjukkan banyak item Hubungkan untuk Anda pilih;
  • Paul White (@SQL_Kiwi) berbicara tentang masalah penyetelan dalam Batasan Pengoptimal dengan Indeks yang Difilter dan juga di Efek Samping yang Tak Terduga dari Menambahkan Indeks yang Difilter; dan,
  • Jes Borland (@grrl_geek) memberi tahu kami Apa yang Dapat Anda (dan Tidak Bisa) Lakukan Dengan Indeks yang Difilter.

Baca semua itu? Dan kau masih di sini? Hebat.

TL; DR dari ini adalah Anda dapat menggunakan indeks yang difilter untuk menyimpan semua "data panas" Anda dalam struktur fisik yang terpisah, dan bahkan pada perangkat keras dasar yang terpisah (Anda mungkin memiliki SSD cepat atau drive PCIe yang tersedia, tetapi dapat' t pegang seluruh meja).

Contoh Singkat

Ada banyak kasus penggunaan di mana sebagian data ditanyai jauh lebih sering daripada yang lain – pikirkan tentang toko ritel yang mengelola pesanan, toko roti yang menjadwalkan pengiriman kue pengantin, atau stadion sepak bola yang mengukur kehadiran dan data konsesi. Dalam kasus ini, sebagian besar atau semua aktivitas kueri sehari-hari berkaitan dengan data "saat ini".

Mari kita tetap sederhana; kita akan membuat database dengan tabel Pesanan yang sangat sempit:

BUAT DATABASE PoorManPartition;PERGI GUNAKAN PoorManPartition;GO CREATE TABLE dbo.Orders( OrderID INT IDENTITY(1,1) PRIMARY KEY, OrderDate DATE NOT NULL DEFAULT SYSUTCDATETIME(), OrderTotal DECIMAL(8,2) --, .. .kolom lain...);

Sekarang, katakanlah Anda memiliki cukup ruang di penyimpanan cepat Anda untuk menyimpan data selama satu bulan (dengan banyak ruang untuk memperhitungkan musim dan pertumbuhan di masa mendatang). Kita dapat menambahkan filegroup baru, dan menempatkan file data di drive cepat.

ALTER DATABASE PoorManPartition ADD FILEGROUP HotData;GO ALTER DATABASE PoorManPartition ADD FILE ( Name =N'HotData', FileName =N'Z:\folder\HotData.mdf', Ukuran =100MB, FileGrowth =25MB) KE FILEGROUP HotData; 

Sekarang, mari buat indeks yang difilter pada grup file HotData, di mana filter tersebut mencakup semuanya dari awal November 2015, dan kolom umum yang terlibat dalam kueri berbasis waktu ada di daftar kunci atau sertakan:

BUAT INDEKS FilteredIndex PADA dbo.Orders(OrderDate) INCLUDE(OrderTotal) WHERE OrderDate>='20151101' AND OrderDate <'20151201' PADA HotData;

Kita dapat menyisipkan beberapa baris dan memeriksa rencana eksekusi untuk memastikan bahwa kueri yang dicakup sebenarnya dapat menggunakan indeks:

INSERT dbo.Orders(OrderDate) VALUES('20151001'),('20151103'),('20151127');GO SELECT index_id, rows FROM sys.partitions WHERE object_id =OBJECT_ID(N'dbo.Orders'); /* Hasil:index_id rows -------- ---- 1 3 2 2*/ SELECT OrderID, OrderDate, OrderTotal FROM dbo.Orders WHERE OrderDate>='20151102' AND OrderDate <'20151106'; 

Rencana eksekusi yang dihasilkan, tentu saja, menggunakan indeks yang difilter (meskipun predikat filter dalam kueri tidak sama persis dengan definisi indeks):

Sekarang, 1 Desember bergulir, dan inilah saatnya untuk menukar data November kami dan menggantinya dengan Desember. Kita cukup membuat kembali indeks yang difilter dengan predikat filter baru, dan menggunakan DROP_EXISTING pilihan:

BUAT INDEKS FilteredIndex PADA dbo.Orders(OrderDate) INCLUDE(OrderTotal) WHERE OrderDate>='20151201' AND OrderDate <'20160101' WITH (DROP_EXISTING =ON) PADA HotData;

Sekarang, kita dapat menambahkan beberapa baris lagi, memeriksa statistik partisi, dan menjalankan kueri sebelumnya dan kueri baru untuk memeriksa indeks yang digunakan:

INSERT dbo.Orders(OrderDate) VALUES('20151202'),('20151205');GO SELECT index_id, rows FROM sys.partitions WHERE object_id =OBJECT_ID(N'dbo.Orders'); /* Hasil:baris index_id -------- ---- 1 5 2 2*/ SELECT OrderID, OrderDate, OrderTotal FROM dbo.Orders WHERE OrderDate>='20151102' AND OrderDate <'20151106'; PILIH OrderID, OrderDate, OrderTotal FROM dbo.Orders WHERE OrderDate>='20151202' AND OrderDate <'20151204';

Dalam hal ini kami mendapatkan pemindaian indeks berkerumun dengan kueri November:

(Tapi itu akan berbeda jika kita memiliki indeks terpisah yang tidak difilter dengan OrderDate sebagai kuncinya.)

Dan saya tidak akan menampilkannya lagi, tetapi dengan kueri Desember, kami mendapatkan pencarian indeks terfilter yang sama seperti sebelumnya.

Anda juga dapat mempertahankan beberapa indeks, satu untuk bulan ini, satu untuk bulan sebelumnya, dan seterusnya, dan Anda dapat mengelolanya secara terpisah (pada tanggal 1 Desember Anda hanya menghapus indeks dari Oktober, dan membiarkan November saja, misalnya) . Anda juga dapat mempertahankan beberapa indeks dengan rentang waktu yang lebih pendek atau lebih lama (minggu ini dan sebelumnya, kuartal saat ini dan sebelumnya), dll. Solusinya cukup fleksibel.

Karena keterbatasan indeks yang difilter, saya tidak akan mencoba untuk mendorong ini sebagai solusi sempurna, atau pengganti lengkap untuk partisi tabel atau tampilan yang dipartisi. Mengganti partisi, misalnya, adalah operasi metadata, sambil membuat ulang indeks dengan DROP_EXISTING dapat memiliki banyak logging (dan karena Anda tidak menggunakan Enterprise Edition, tidak dapat dijalankan secara online). Anda mungkin juga menemukan bahwa tampilan yang dipartisi lebih mempercepat Anda – ada lebih banyak pekerjaan untuk mempertahankan tabel fisik terpisah dan batasan yang memungkinkan tampilan yang dipartisi, tetapi hasil dalam hal kinerja kueri mungkin lebih baik dalam beberapa kasus.

Otomasi

Tindakan membuat ulang indeks dapat diotomatisasi dengan cukup mudah, menggunakan pekerjaan sederhana yang melakukan sesuatu seperti ini sebulan sekali (atau berapa pun ukuran jendela "panas" Anda):

DECLARE @sql NVARCHAR(MAX), @dt TANGGAL =DATEADD(DAY, 1-DAY(GETDATE()), GETDATE()); SET @sql =N'CREATE INDEX FilteredIndex PADA dbo.Orders(OrderDate) INCLUDE(OrderTotal) WHERE OrderDate>=''' + CONVERT(CHAR(8), @dt, 112) + N''' WITH (DROP_EXISTING =ON ) DI HotData;'; EXEC PoorManPartition.sys.sp_executesql @sql;

Anda juga dapat membuat beberapa indeks beberapa bulan sebelumnya, seperti membuat partisi masa depan terlebih dahulu – lagi pula, indeks masa depan tidak akan menempati ruang apa pun sampai ada data yang relevan dengan predikatnya. Dan Anda bisa membuang indeks yang mengelompokkan data lama yang sekarang Anda inginkan menjadi dingin.

Melihat ke belakang

Setelah saya menyelesaikan artikel ini, tentu saja, saya menemukan posting Kimberly Tripp lainnya, yang harus Anda baca sebelum melanjutkan dengan apa pun yang saya sarankan di sini (dan yang telah saya baca sebelum saya mulai):

  • Bagaimana dengan Filtered Index daripada Partitioning?

Untuk beberapa alasan, Kimberly lebih menyukai tampilan yang dipartisi untuk mengimplementasikan sesuatu yang mirip dengan mempartisi di Edisi Standar; namun, untuk skenario tertentu, penggunaan indeks yang difilter masih cukup menarik bagi saya untuk melanjutkan eksperimen saya. Salah satu area di mana indeks yang difilter dapat bermanfaat adalah ketika data "panas" Anda memiliki banyak kriteria – tidak hanya diiris menurut tanggal, tetapi juga oleh atribut lain (mungkin Anda ingin kueri cepat terhadap semua pesanan dari bulan ini yang ditujukan untuk tingkat tertentu pelanggan atau di atas jumlah dolar tertentu).

Berikutnya…

Dalam posting mendatang, saya akan bermain dengan konsep ini pada sistem kelas atas, dengan beberapa volume dan beban kerja dunia nyata. Saya ingin menemukan perbedaan kinerja antara solusi ini, indeks penutup yang tidak difilter, tampilan yang dipartisi, dan tabel yang dipartisi. Di dalam VM pada laptop dengan hanya SSD yang tersedia mungkin tidak akan menghasilkan pengujian yang realistis atau adil dalam skala besar.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pertanyaan SQL

  2. Cara membuat Replikasi Snapshot

  3. Tren Basis Data 2019 – SQL vs. NoSQL, Basis Data Teratas, Penggunaan Basis Data Tunggal vs. Banyak

  4. Menggabungkan File Data dengan Statistica, Bagian 1

  5. Cara Bergabung di Beberapa Kolom