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

Bendera Jejak 2389 dan Penaksir Kardinalitas baru

Salah satu tanda pelacakan SQL Server yang sudah ada untuk sementara waktu adalah 2389. Ini sering dibahas dengan 2390, tetapi saya hanya ingin fokus pada 2389 untuk posting ini. Bendera jejak diperkenalkan di SQL Server 2005 SP1, yang dirilis pada 18 April 2006 (menurut http://sqlserverbuilds.blogspot.co.uk/), jadi sudah ada selama lebih dari 10 tahun. Bendera jejak mengubah perilaku mesin, dan 2389 memungkinkan pengoptimal untuk mengidentifikasi statistik yang sedang naik dan mencapnya seperti itu (sering disebut "masalah kunci naik"). Ketika ini terjadi, statistik akan diperbarui secara otomatis pada waktu kompilasi kueri, yang berarti bahwa pengoptimal memiliki informasi tentang nilai tertinggi dalam tabel (dibandingkan saat tanda pelacakan tidak digunakan).

Saya baru-baru ini berdiskusi dengan klien tentang penggunaan tanda pelacakan ini, dan itu muncul karena jenis skenario ini:

  • Anda memiliki tabel besar yang memiliki INT sebagai kunci utama, dan dikelompokan.
  • Anda memiliki indeks nonclustered yang mengarah pada kolom DATETIME.
  • Tabel memiliki sekitar 20 juta baris di dalamnya, dan di mana saja dari 5.000 hingga 100.000 baris ditambahkan setiap hari.
  • Statistik diperbarui setiap malam sebagai bagian dari tugas pemeliharaan Anda.
  • Statistik pembaruan otomatis diaktifkan untuk database, tetapi meskipun 100.000 baris ditambahkan ke tabel, itu jauh lebih sedikit dari 4 juta baris (20%) yang diperlukan untuk menjalankan pembaruan otomatis.
  • Saat pengguna membuat kueri tabel menggunakan tanggal dalam predikat, kinerja kueri bisa bagus, atau bisa buruk.

Peluru terakhir itu hampir membuatnya terdengar seperti masalah sensitivitas parameter, tetapi tidak. Dalam hal ini, ini adalah masalah statistik. Saran saya kepada klien adalah menggunakan TF 2389, atau memperbarui statistik lebih sering sepanjang hari (misalnya melalui Agen Pekerjaan). Kemudian saya pikir saya akan melakukan beberapa pengujian, karena klien menjalankan SQL Server 2014.  Di sinilah segalanya menjadi menarik.

Penyiapan

Kami akan membuat tabel yang disebutkan di atas untuk pengujian dalam build RTM SQL Server 2016, dalam database WideWorldImporters, dan saya akan mengatur mode kompatibilitas ke 110 pada awalnya:

GUNAKAN [master];GORESTORE DATABASE [WideWorldImporters]FROM  DISK =N'C:\Backups\WideWorldImporters-Full.bak'WITH  FILE =1,MOVE N'WWI_Primary' KE N'C:\Databases\WideWorldImporters\WideWorldImporters .mdf',PINDAHKAN N'WWI_UserData' KE N'C:\Databases\WideWorldImporters\WideWorldImporters_UserData.ndf',PINDAHKAN N'WWI_Log' KE N'C:\Databases\WideWorldImporters\WideWorldImporters.ldf',MOVE N'_WWI_1'InMemory N'WWI_1 N'C:\Databases\WideWorldImporters\WideWorldImporters_InMemory_Data_1',NOUNLOAD, REPLACE, STATS =5;GO ALTER DATABASE [WideWorldImporters] SET COMPATIBILITY_LEVEL =110;GO GUNAKAN [WideWorldImporters][Atau CREATE TABLE][Atau BUAT]. ] [int] NOT NULL,[CustomerID] [int] NOT NULL,[SalespersonPersonID] [int] NOT NULL,[PickedByPersonID] [int] NULL,[ContactPersonID] [int] NOT NULL,[BackorderOrderID] [int] NULL, [TanggalPesanan] [tanggal] NOT NULL,[ExpectedDeliveryDate] [tanggal] NOT NULL,[CustomerPurchaseOrderNumber] [nvarchar](20) NULL,[IsUndersupplyBackordered] [bit] NOT NULL,[Komentar] [nvarchar ](maks) NULL,[Petunjuk Pengiriman] [nvarchar](maks) NULL,[Komentar Internal] [nvarchar](maks) NULL,[PemilihanSelesai] [datetime2](7) NULL,[TerakhirDiedit Oleh] [int] NOT NULL,[TerakhirDieditKetika ] [datetime2](7) NOT NULL,CONSTRAINT [PK_Sales_BigOrders] PRIMARY KEY CLUSTERED([OrderID] ASC)DENGAN (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROWATA_LOCKS)] [D =USERATA_LOCKS] LOW_ROWON_LOCKS] DI [USERDATA] TEXTIMAGE_ON [USERDATA];

Selanjutnya kita akan memuat sekitar 24 juta baris ke dalam BigOrders, dan membuat indeks nonclustered pada OrderDate.

ATUR NOCOUNT AKTIF; MENYATAKAN @Loops KECIL =0, @IDIncrement INT =75000; SAAT @Loops <325 -- sesuaikan ini untuk menambah atau mengurangi jumlah baris yang ditambahkanBEGININSERT [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID], [OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Comments],[DeliveryInstructions],[InternalComments],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen]) +SELECT[IDPesanan ],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Komentar],[DeliveryInstructions],[Petunjuk] [Terakhir Diedit Oleh],[Terakhir Diedit Kapan]DARI [Penjualan].[Pesanan]; POS PEMERIKSAAN; SET @Loops =@Loops + 1;SET @IDIncrement =@IDIncrement + 75000;END CREATE NONCLUSTERED INDEX [NCI_BigOrders_OrderDate]ON [Sales].[BigOrders] ([OrderDate], CustomerID);

Jika kita memeriksa histogram untuk indeks nonclustered, kita melihat tanggal tertinggi adalah 31-05-2016:

DBCC SHOW_STATISTICS ('Sales.BigOrders',[NCI_BigOrders_OrderDate]);


Statistik untuk NCI pada OrderDate

Jika kami meminta tanggal di luar itu, perhatikan perkiraan jumlah baris:

SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='2016-06-01';


Rencanakan saat menanyakan tanggal di luar histogram

Ini 1, karena nilainya di luar histogram. Dan dalam hal ini, tidak apa-apa, karena tidak ada baris dalam tabel setelah tanggal 31 Mei 2016.  Tapi mari kita tambahkan beberapa, lalu jalankan kembali kueri yang sama:

MASUKKAN [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderUndersupply ],[Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen])SELECT[OrderID] + 25000000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[ BackorderOrderID],'06-01-2016',[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Comments],[DeliveryInstructions],[InternalComments],[PemilihanSelesai],[LastEditedBy],[ROM[TerakhirDiedit] .[Pesanan];GO SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='2016-06-01';


Rencanakan setelah menambahkan baris setelah 31 Mei

Perkiraan jumlah baris masih 1.  Tapi di sinilah hal-hal menarik. Mari ubah mode kompatibilitas ke 130 sehingga kita menggunakan Penaksir Kardinalitas baru dan melihat apa yang terjadi.

GUNAKAN [master];GO ALTER DATABASE [WideWorldImporters] SET COMPATIBILITY_LEVEL =130GO GUNAKAN [WideWorldImporters];GO SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='06-01'; 


Rencanakan setelah menambahkan baris untuk 1 Juni, menggunakan CE baru

Bentuk denah kami sama, tetapi sekarang perkiraan kami adalah 4.898 baris. CE baru memperlakukan nilai-nilai di luar sejarah secara berbeda dari CE lama. Jadi…apakah kita membutuhkan bendera jejak 2389?

Ujian – Bagian I

Untuk pengujian pertama, kita akan tetap dalam mode kompatibilitas 110 dan menjalankan apa yang akan kita lihat dengan 2389.  Saat menggunakan tanda pelacakan ini, Anda dapat mengaktifkannya sebagai parameter startup di layanan SQL Server, atau Anda dapat menggunakan DBCC TRACEON untuk mengaktifkannya di seluruh instance. Pahami bahwa di lingkungan produksi Anda, jika Anda menggunakan DBCC TRACEON untuk mengaktifkan tanda pelacakan, saat instance dimulai ulang tanda pelacakan tidak akan berlaku.

Dengan mengaktifkan tanda pelacakan, statistik harus diperbarui tiga (3) kali sebelum pengoptimal akan mencapnya sebagai menaik. Kami akan memaksa empat pembaruan untuk ukuran yang baik dan menambahkan lebih banyak baris di antara setiap pembaruan.

GUNAKAN [master];GO ALTER DATABASE [WideWorldImporters] SET COMPATIBILITY_LEVEL =110;GO DBCC TRACEON (2389, -1);GO GUNAKAN [WideWorldImporters];GO UPDATE STATISTICS [Penjualan].[BigOrders] [NCI_BigOrders_Orders] MASUKKAN [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[BackorderUndersupply], Komentar],[DeliveryInstructions],[InternalComments],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen])SELECT[OrderID] + 25100000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[BackorderOrderID] '02-06-2016',[TanggalPengiriman yang Diharapkan],[PelangganPurchaseOrderNumber],[IsUndersupplyBackordered],[Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PemilihanSelesai],[LastEditedBy],[LastEditedWhen][Dari [Penjualan] ];PERBARUI STATISTIK [Penjualan].[Pesanan Besar] [NCI_BigOrders_TanggalPesanan];MASUKKAN [Penjualan].[Pesanan Besar]( [IDPesanan],[IDPelanggan ],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Komentar],[DeliveryInstructions],[Petunjuk] [LastEditedBy][LastEditedWhen])SELECT[OrderID] + 25200000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],'06-03-2016',[Tanggal Pengiriman yang Diharapkan],[PelangganPembelian],NomorPesanan [IsUndersupplyBackordered],[Komentar],[DeliveryInstructions],[InternalComments],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen]FROM [Penjualan].[Pesanan];PERBARUI STATISTIK [Penjualan].[Pesanan Besar] [NCI_OrderBigDate; MASUKKAN [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[BackorderUndersupply] [Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PemilihanSelesai],[Terakhir Diedit Oleh] ,[LastEditedWhen])SELECT[OrderID] + 25300000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],'2016-06-04',[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[BackorderUndersupply ],[Komentar],[DeliveryInstructions],[InternalComments],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen]FROM [Sales].[Orders];GO UPDATE STATISTICS [Sales].[BigOrders] [NCI_BigOrders_OrderDate]; 

Jika kita memeriksa statistik lagi, dan menggunakan bendera jejak 2388 untuk menampilkan informasi tambahan, kita melihat bahwa statistik sekarang ditandai sebagai Ascending:

DBCC TRACEON (2388);GO DBCC SHOW_STATISTICS ('Sales.BigOrders',[NCI_BigOrders_OrderDate]);


NCI pada OrderDate ditandai sebagai ASC

Jika kami menanyakan tanggal di masa mendatang, saat statistik sepenuhnya mutakhir, kami melihat bahwa statistik tersebut masih memperkirakan 1 baris:

SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='06-06-05';


Rencanakan setelah TF 2389 diaktifkan, tetapi tidak ada baris di luar histogram

Sekarang kita akan menambahkan baris untuk tanggal 5 Juni dan menjalankan kueri yang sama lagi:

MASUKKAN [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderUndersupply ],[Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen])SELECT[OrderID] + 25400000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[ContactPersonID] BackorderOrderID],'06-06-05',[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Comments],[DeliveryInstructions],[InternalComments],[PemilihanSelesai],[LastEditedBy],[ROM[TerakhirDiedit] .[Pesanan];GO SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='06-06-05';


Rencanakan setelah TF 2389 diaktifkan, 70 ribu+ baris ditambahkan di luar histogram

Estimasi kami bukan lagi 1, melainkan 22.595. Sekarang, hanya untuk bersenang-senang, mari nonaktifkan tanda pelacakan dan lihat perkiraannya (saya akan menghapus cache prosedur, karena menonaktifkan tanda pelacakan tidak akan memengaruhi apa yang saat ini ada di cache).

DBCC TRACEOFF (2389, -1);GO DBCC FREEPROCCACHE;GO SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='2016-06-05';


Rencana setelah TF 2389 *dinonaktifkan*, 70 ribu+ baris ditambahkan di luar histogram

Kali ini saya mendapatkan perkiraan 1 baris lagi. Meskipun statistik dicap sebagai menaik, jika bendera pelacakan 2389 tidak diaktifkan, statistik tersebut hanya memperkirakan 1 baris saat Anda meminta nilai di luar histogram.

Kami telah menunjukkan bahwa trace flag 2389 melakukan apa yang kami harapkan – apa yang selalu dilakukannya – saat menggunakan Penaksir Kardinalitas lama. Sekarang mari kita lihat apa yang terjadi dengan yang baru.

Ujian – Bagian II

Agar menyeluruh, saya akan mengatur ulang semuanya. Saya akan membuat database lagi, mengatur mode kompatibilitas ke 130, memuat data pada awalnya, lalu mengaktifkan bendera pelacakan 2389 dan memuat tiga set data dengan pembaruan statistik di antaranya.

GUNAKAN [master];PERGI KEMBALIKAN DATABASE [WideWorldImporters]FROM  DISK =N'C:\Backups\WideWorldImporters-Full.bak'DENGAN  FILE =1,MOVE N'WWI_Primary' KE N'C:\Databases\WideWorldImporters\ WideWorldImporters.mdf',MOVE N'WWI_UserData' KE N'C:\Databases\WideWorldImporters\WideWorldImporters_UserData.ndf',MOVE N'WWI_Log' KE N'C:\Databases\WideWorldImporters\WideWorldImporters.Nldf' KE N'C:\Databases\WideWorldImporters\WideWorldImporters_InMemory_Data_1',NOUNLOAD, REPLACE, STATS =5;GO GUNAKAN [master];GO ALTER DATABASE [WideWorldImporters] SET COMPATIBILITY_LEVEL =130;GO GUNAKAN [WideWorldImporters] .[BigOrders]([OrderID] [int] NOT NULL,[CustomerID] [int] NOT NULL,[SalespersonPersonID] [int] NOT NULL,[PickedByPersonID] [int] NULL,[ContactPersonID] [int] NOT NULL,[ BackorderOrderID] [int] NULL,[OrderDate] [date] NOT NULL,[ExpectedDeliveryDate] [date] NOT NULL,[CustomerPurchaseOrderNumber] [nvarchar](20) NULL,[IsUndersupplyBackordered] [bit] NOT NULL,[Co mments] [nvarchar](max) NULL,[DeliveryInstructions] [nvarchar](max) NULL,[InternalComments] [nvarchar](max) NULL,[PickingCompletedWhen] [datetime2](7) NULL,[LastEditedBy] [int] NOT NULL,[LastEditedWhen] [datetime2](7) NOT NULL,CONSTRAINT [PK_Sales_BigOrders] PRIMARY KEY CLUSTERED([OrderID] ASC)DENGAN (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =LOCKSLOW_P_ LOCKSLOW_P_ LOCKSLOW_P_ OFF_ =OFF_ [USERDATA]) ON [USERDATA] TEXTIMAGE_ON [USERDATA];PERGI SET NOCOUNT ON; DECLARE @Loops SMALLINT =0;DECLARE @IDIncrement INT =75000; SAAT @Loops <325 -- sesuaikan ini untuk menambah atau mengurangi jumlah baris yang ditambahkanBEGININSERT [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID], [OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Comments],[DeliveryInstructions],[InternalComments],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen]) +SELECT[IDPesanan ],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Komentar],[DeliveryInstructions],[Petunjuk] [Terakhir Diedit Oleh],[Terakhir Diedit Kapan]DARI [Penjualan].[Pesanan]; POS PEMERIKSAAN; SET @Loops =@Loops + 1;SET @IDIncrement =@IDIncrement + 75000;END CREATE NONCLUSTERED INDEX [NCI_BigOrders_OrderDate]ON [Penjualan].[BigOrders] ([OrderDate], CustomerID);GO INSERT [Penjualan].[BigOrders] ( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered,[]Pengiriman] InternalComments],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen])SELECT[OrderID] + 25000000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],'06-01', [TanggalPengiriman yang Diharapkan],[PelangganPurchaseOrderNumber],[IsUndersupplyBackordered],[Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PemilihanSelesai],[TerakhirDiedit Oleh],[TerakhirDieditKapan]DARI [Penjualan].[Pesanan TRACE];LANJUTKAN -1);PERBARUI STATISTIK [Penjualan].[BigOrders] [NCI_BigOrders_OrderDate];GO INSERT [Sales].[BigOrders]( [OrderID],[CustomerID],[Salesperson PersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Komentar],[DeliveryInstructions],[PickingComlet] ,[LastEditedWhen])SELECT[OrderID] + 25100000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],'06-2016-02',[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[BackorderUndersupply ],[Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PemilihanSelesai],[LastEditedBy],[LastEditedWhen]FROM [Penjualan].[Pesanan];GO UPDATE STATISTICS [Penjualan].[BigOrders] [NCI_BigOrders_GO INSERTate]; [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupp ],[Petunjuk Pengiriman],[Komentar Internal],[PemilihanSelesai],[LastEditedBy],[LastEditedW hen])SELECT[OrderID] + 25200000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],'06-06-03',[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[Backordered],supply [Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PemilihanSelesaiKapan],[LastEditedBy],[LastEditedWhen]FROM [Penjualan].[Pesanan];GO UPDATE STATISTICS [Penjualan].[Pesanan Besar] [NCI_BigOrders_OrderDate [Penjualan];GO INSERT ].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[Backordered,]supply [Petunjuk Pengiriman],[Komentar Internal],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen])SELECT[OrderID] + 25300000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID], 06-04',[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Komentar],[Petunjuk Pengiriman],[InternalCo mments],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen]FROM [Sales].[Orders];GO UPDATE STATISTICS [Sales].[BigOrders] [NCI_BigOrders_OrderDate];

Ok, jadi data kita sudah terisi penuh. Jika kami memeriksa statistik lagi, dan menggunakan tanda jejak 2388 untuk menampilkan informasi tambahan, kami melihat bahwa statistik kembali ditandai sebagai Naik:

DBCC TRACEON (2388);GO DBCC SHOW_STATISTICS ('Sales.BigOrders',[NCI_BigOrders_OrderDate]);


Statistik NCI OrderDate ditandai sebagai ASC dengan TF 2389 dan mode kompatibilitas 130

Oke, jadi mari kita tanya lagi tanggal 5 Juni:

SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='06-06-05';


Rencanakan dengan CE baru, tidak ada baris di luar histogram

Perkiraan kami adalah 4.922. Tidak seperti pada pengujian pertama kami, tetapi jelas tidak 1.  Sekarang kami akan menambahkan beberapa baris untuk tanggal 5 Juni dan membuat kueri ulang:

MASUKKAN [Penjualan].[BigOrders]( [OrderID],[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[BackorderOrderID],[OrderDate],[ExpectedDeliveryDate],[CustomerPurchaseOrderUndersupply ],[Komentar],[Petunjuk Pengiriman],[Komentar Internal],[PickingCompletedWhen],[LastEditedBy],[LastEditedWhen])SELECT[OrderID] + 25400000,[CustomerID],[SalespersonPersonID],[PickedByPersonID],[ContactPersonID],[ContactPersonID] BackorderOrderID],'06-06-05',[ExpectedDeliveryDate],[CustomerPurchaseOrderNumber],[IsUndersupplyBackordered],[Comments],[DeliveryInstructions],[InternalComments],[PemilihanSelesai],[LastEditedBy],[ROM[TerakhirDiedit] .[Pesanan];GO SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='06-06-05';


Rencanakan dengan CE baru, dengan 70 ribu+ baris di luar histogram

Perkiraannya sama. Jadi sekarang, bagaimana jika kita mematikan trace flag 2389?

DBCC TRACEOFF (2389, -1);GO DBCC FREEPROCCACHE;GO SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='2016-06-05';


Rencanakan dengan CE baru tetapi TF 2389 TIDAK diaktifkan, dengan 70K+ baris di luar apa yang ada di histogram

Perkiraannya sedikit berubah, menjadi 4.930, tetapi berubah. Ini memberitahu saya bahwa jejak bendera 2389 memiliki beberapa efek pada perkiraan, tetapi berapa banyak tidak diketahui.

Ujian – Bagian III

Saya menjalankan satu pengujian terakhir, di mana saya memulihkan database, menyetel mode kompatibilitas ke 130, memuat semua data lagi, memperbarui statistik beberapa kali, tetapi TIDAK mengaktifkan bendera pelacakan 2389.  Kodenya sama dengan Bagian II, kecuali untuk menggunakan DBCC TRACEON untuk mengaktifkan 2389.  Saat saya membuat kueri untuk 5 Juni, sebelum dan sesudah menambahkan data, perkiraan jumlah baris adalah 4.920.

Apa artinya?

Untuk meringkas, saat menggunakan mode kompatibilitas 110 atau lebih rendah, trace flag 2389 berfungsi seperti biasanya. Namun saat menggunakan mode kompatibilitas 120 atau lebih tinggi, dan dengan demikian CE baru, perkiraannya tidak sama dibandingkan dengan CE lama, dan dalam kasus khusus ini, tidak jauh berbeda apakah menggunakan tanda jejak atau tidak.

Jadi apa yang harus Anda lakukan? Tes, seperti biasa. Saya belum menemukan apa pun yang didokumentasikan di MSDN yang menyatakan bahwa trace flag 2389 tidak didukung dengan mode kompatibilitas 120 dan lebih tinggi, saya juga tidak menemukan apa pun yang mendokumentasikan perubahan perilaku. Saya merasa sangat menarik bahwa perkiraannya berbeda (dalam hal ini jauh lebih rendah) dengan CE baru. Itu berpotensi menjadi masalah, tetapi ada banyak faktor yang berperan dalam hal perkiraan, dan ini adalah kueri yang sangat sederhana (satu tabel, satu predikat). Dalam hal ini, perkiraannya sangat jauh (4.920 baris versus 22.595 baris untuk tanggal 5 Juni).

Jika saya menjalankan ulang kueri untuk tanggal yang memiliki jumlah baris yang sama dengan adalah dalam histogram, saya mendapatkan rencana serupa, tetapi berjalan secara paralel:

SELECT CustomerID, OrderID, SalespersonPersonIDFROM [Sales].[BigOrders]WHERE [OrderDate] ='2016-06-02';


Rencanakan kueri yang menggunakan tanggal dalam histogram (baru CE, tanpa TF)

Perkiraannya juga lebih akurat (68.318). Rencananya tidak berubah secara signifikan dalam kasus ini, tetapi biayanya jelas lebih tinggi. Pada titik tertentu, tergantung pada jumlah baris yang akan dikembalikan, ini bisa mengarah ke pemindaian tabel.

Panduan terbaik saat ini jika Anda menjalankan 2014 atau lebih tinggi dan mode kompatibilitas 120 atau lebih tinggi, dan Anda memiliki kolom terdepan dalam statistik yang naik, adalah untuk menguji. Jika Anda menemukan bahwa Penaksir Kardinalitas baru tidak memberikan perkiraan sebaik CE lama, maka saya akan merekomendasikan untuk mengajukan item Connect sehingga tim produk mengetahuinya. Selalu ada kasus satu kali dan unik, tetapi jika banyak pelanggan (baca:ANDA) secara konsisten menemukan perilaku yang sama – dan itu tidak ideal – maka penting untuk memberi tahu tim pengembangan tentang hal itu.

Ini adalah item penting lainnya yang perlu dipertimbangkan saat meningkatkan ke 2014 atau 2016 – dan pengingat untuk bukan abaikan pengujian Anda (dan omong-omong, Query Store akan sangat berguna di sini dengan 2016). Ayo teman-teman.


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

  2. Penyetelan:Tempat yang Baik untuk Memulai

  3. Manfaat dan Keamanan di Amazon Relational Database Service

  4. Alasan Lain untuk Menggunakan petunjuk NOEXPAND di Edisi Perusahaan

  5. Dasar-dasar ekspresi tabel, Bagian 8 – CTE, pertimbangan pengoptimalan lanjutan