Kami memiliki database SQL Server yang dipartisi besar menggunakan statistik tambahan. Semua indeks dipartisi selaras. Ketika kami mencoba untuk membangun kembali sebuah partisi secara online dengan partisi semua statistik hilang setelah indeks dibangun kembali.
Di bawah ini adalah skrip untuk mereplikasi masalah di SQL Server 2014 dengan database AdventureWorks2014.
--Example against AdventureWorks2014 Database
CREATE PARTITION FUNCTION TransactionRangePF1 (DATETIME)
AS RANGE RIGHT FOR VALUES
(
'20130501', '20130601', '20130701', '20130801',
'20130901', '20131001', '20131101', '20131201',
'20140101', '20140201', '20140301'
);
GO
CREATE PARTITION SCHEME TransactionsPS1 AS PARTITION TransactionRangePF1 TO
(
[PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY],
[PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY],
[PRIMARY], [PRIMARY], [PRIMARY]
);
GO
CREATE TABLE dbo.TransactionHistory
(
TransactionID INT NOT NULL, -- not bothering with IDENTITY here
ProductID INT NOT NULL,
ReferenceOrderID INT NOT NULL,
ReferenceOrderLineID INT NOT NULL DEFAULT (0),
TransactionDate DATETIME NOT NULL DEFAULT (GETDATE()),
TransactionType NCHAR(1) NOT NULL,
Quantity INT NOT NULL,
ActualCost MONEY NOT NULL,
ModifiedDate DATETIME NOT NULL DEFAULT (GETDATE()),
CONSTRAINT CK_TransactionType
CHECK (UPPER(TransactionType) IN (N'W', N'S', N'P'))
)
ON TransactionsPS1 (TransactionDate);
INSERT INTO dbo.TransactionHistory
SELECT * FROM Production.TransactionHistory
-- SELECT * FROM sys.partitions
-- WHERE object_id = OBJECT_ID('dbo.TransactionHistory');
CREATE NONCLUSTERED INDEX IDX_ProductId ON dbo.TransactionHistory (ProductId)
WITH (DATA_COMPRESSION = ROW, STATISTICS_INCREMENTAL=ON)
ON TransactionsPS1 (TransactionDate)
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT 'Stats are avialable'
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = 9 WITH (ONLINE = ON , DATA_COMPRESSION = ROW)
PRINT 'After online index rebuild by partition stats are now gone'
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT 'Rebuild the stats with a rebuild for all paritions (this works)'
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = ALL WITH (ONLINE = ON , DATA_COMPRESSION = ROW,
STATISTICS_INCREMENTAL = ON)
PRINT 'Stats are back'
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT 'Works correctly for an offline rebuild by partition'
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = 9 WITH (ONLINE = OFF , DATA_COMPRESSION = ROW)
--stats still there
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD
PARTITION = 9 WITH (ONLINE = ON , DATA_COMPRESSION = ROW)
DBCC SHOW_STATISTICS('dbo.TransactionHistory', IDX_ProductId);
PRINT' stats are gone!!!!!!'
Seperti yang ditunjukkan, kami tidak dapat membangun kembali indeks berdasarkan partisi online tanpa kehilangan semua statistik untuk indeks. Ini adalah masalah perawatan utama bagi kami. Tampaknya hampir bahwa opsi statistik tambahan perlu menjadi bagian dari sintaks indeks ulang tunggal atau opsi online perlu menanganinya dengan benar seperti yang dilakukan opsi offline.
Tolong beri tahu saya jika saya kehilangan sesuatu?
Pembaruan:
Sejauh kebutuhan kami akan statistik tambahan: Kami mempartisi berdasarkan id pelanggan internal dan bukan tanggal. Jadi, ketika klien baru dimasukkan (data back-load besar) kami cukup memperbarui statistik untuk partisi dan dengan cepat menghindari rencana buruk yang dibuat untuk pelanggan baru ini. Saya pikir saya akan mengajukannya dengan Microsoft sebagai bug dan melihat apa yang mereka katakan dan pergi dengan solusi hanya sampling ulang statistik untuk partisi itu.
Hubungkan laporan bug:
Statistik menghilang setelah indeks online dibangun kembali dengan statistik tambahan
Pembaruan: Microsoft telah mengkonfirmasi bahwa itu adalah bug.
Jawaban:
Tidak yakin apakah itu bug, per se tapi itu jelas suatu kejadian yang menarik. Rekondisi partisi online baru di SQL Server 2014 sehingga mungkin ada beberapa internal untuk menyortir dengan ini.
Inilah penjelasan terbaik saya untuk Anda. Statistik tambahan benar-benar mengharuskan semua partisi disampel pada tingkat yang sama sehingga ketika mesin menggabungkan halaman statistik, dapat yakin bahwa distribusi sampel dapat dibandingkan.
REBUILD
tentu sampel data pada tingkat sampel 100%. Tidak ada jaminan bahwa laju sampel 100% pada partisi 9 akan selalu menjadi laju sampel yang tepat dari sisa partisi. Karena ini, sepertinya mesin tidak dapat menggabungkan sampel dan Anda berakhir dengan gumpalan statistik kosong. Namun, objek statistik masih ada:Anda dapat mengisi gumpalan melalui sejumlah cara:
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE;
atau
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE ON PARTITIONS (9);
atau Anda bisa menunggu AutoStats untuk memperbarui pada kompilasi pertama dari rencana permintaan menggunakan objek itu:
Setelah mengatakan semua itu, pos yang mencerahkan ini oleh Erin Stellato menyoroti apa yang kemudian dianggap sebagai kekurangan utama dari statistik tambahan. Data tingkat partisi mereka tidak digunakan oleh pengoptimal dalam pembuatan paket kueri, mengurangi manfaat statistik tambahan yang diperkirakan. Lalu, apa manfaat statistik inkremental saat ini? Saya akan menyampaikan bahwa utilitas utama mereka adalah dalam kemampuan untuk sampel tabel besar lebih konsisten pada tingkat yang lebih tinggi daripada dengan statistik tradisional.
Menggunakan contoh Anda, beginilah tampilannya:
Pembaruan statistik fullscan pada tambahan biaya statistik 131 ms. Pembaruan statistik fullscan pada statistik non-partisi-aligned 66 ms. Statistik yang tidak selaras lebih lambat kemungkinan besar karena biaya overhead yang dikeluarkan dengan menggabungkan halaman statistik individu kembali ke histogram utama. Namun, menggunakan objek statistik partisi-sejajar, kita dapat memperbarui satu partisi dan menggabungkannya kembali ke gumpalan histogram utama dalam 5 ms. Jadi pada titik ini administrator dengan statistik tambahan dihadapkan dengan keputusan. Mereka dapat mengurangi waktu pemeliharaan statistik keseluruhan dengan hanya memperbarui partisi yang secara tradisional perlu diperbarui, atau mereka dapat bereksperimen dengan laju sampel yang lebih tinggi sehingga mereka berpotensi mendapatkan lebih banyak sampel baris dalam periode waktu yang sama dengan jangka waktu pemeliharaan sebelumnya. Yang pertama memungkinkan ruang bernapas di jendela pemeliharaan, yang terakhir mungkin mendorong statistik di meja yang sangat besar ke tempat di mana pertanyaan mendapatkan rencana yang lebih baik berdasarkan statistik yang lebih akurat. Ini bukan jaminan dan jarak tempuh Anda mungkin beragam.
Pembaca dapat melihat bahwa 66 ms bukan waktu pembaruan statistik yang menyakitkan pada tabel ini, jadi saya mencoba menyiapkan tes pada set data stackexchange. Ada 6.418.608 posting (tidak termasuk posting StackOverflow dan semua posting dari 2012 - kesalahan data di pihak saya) di dump terbaru yang saya unduh.
Saya telah mempartisi data oleh
[CreationDate]
karena ... demo.Berikut adalah beberapa pengaturan waktu untuk beberapa skenario standar yang cantik (100% - pembangunan kembali indeks, default - statistik pembaruan otomatis atau
UPDATE STATISTICS
tanpa laju sampel yang ditentukan:Katakanlah kita lebih canggih dari skenario default ini dan telah memutuskan bahwa tingkat sampel 10% adalah tingkat minimum yang seharusnya memberi kita rencana yang kita butuhkan sambil menjaga waktu pemeliharaan ke jangka waktu yang masuk akal.
Sejauh ini tidak ada manfaat yang jelas untuk memiliki statistik tambahan. Namun, jika kami memanfaatkan DMV yang tidak berdokumen
sys.dm_db_stats_properties_internal()
(di bawah), Anda bisa mendapatkan wawasan tentang partisi mana yang ingin Anda perbarui. Katakanlah kami membuat perubahan pada data di partisi 3 dan kami ingin memastikan statistik baru untuk kueri yang masuk. Berikut ini pilihan kami:Di sinilah kita perlu mengambil keputusan. Apakah kita mengambil kemenangan 63 ms. pembaruan statistik berbasis partisi, atau apakah kita meningkatkan laju sampel lebih tinggi? Katakanlah kita bersedia untuk mengambil hit sampel awal sebesar 50% pada statistik tambahan:
Kami dapat mengambil sampel lebih banyak data, mungkin menyiapkan pengoptimal untuk membuat perkiraan yang lebih baik tentang data kami (meskipun belum menggunakan statistik tingkat partisi) dan kami dapat melakukan ini lebih cepat sekarang karena kami memiliki statistik tambahan.
Namun, satu hal yang menyenangkan untuk dipecahkan. Bagaimana dengan pembaruan statistik sinkron? Apakah tingkat sampel 50% dipertahankan bahkan ketika autostats masuk?
Saya menghapus data dari partisi 3 dan menjalankan kueri pada CreationDate dan memeriksa kemudian memeriksa tarif dengan kueri yang sama di bawah ini. Tingkat sampel 50% dipertahankan.
Jadi, cerita panjang pendek: Statistik tambahan dapat menjadi alat yang berguna dengan jumlah pemikiran yang tepat dan pekerjaan pengaturan awal. Namun, Anda harus tahu masalah yang Anda coba selesaikan dan kemudian Anda harus menyelesaikannya dengan tepat. Jika Anda mendapatkan perkiraan kardinalitas yang buruk, Anda mungkin bisa mendapatkan rencana yang lebih baik dengan laju sampel strategis dan beberapa intervensi yang diinvestasikan. Namun, Anda hanya mendapatkan sebagian kecil dari manfaatnya karena histogram yang digunakan adalah halaman statistik tunggal yang digabungkan dan bukan informasi tingkat partisi. Jika Anda merasa sakit di jendela pemeliharaan, maka mungkin statistik tambahan dapat membantu Anda, tetapi mungkin akan mengharuskan Anda menyiapkan proses intervensi pemeliharaan sentuhan tinggi. Bagaimanapun,:
Semoga ini membantu
sumber