Apakah ada dokumentasi atau penelitian tentang perubahan dalam SQL Server 2016 untuk bagaimana kardinalitas diperkirakan untuk predikat yang berisi SUBSTRING () atau fungsi string lainnya?
Alasan saya bertanya adalah karena saya melihat kueri yang kinerjanya menurun dalam mode kompatibilitas 130 dan alasannya terkait perubahan dalam estimasi jumlah baris yang cocok dengan klausa WHERE yang berisi panggilan ke SUBSTRING (). Saya memperbaiki masalah dengan penulisan ulang kueri, tetapi saya bertanya-tanya apakah ada yang mengetahui dokumentasi tentang perubahan di area ini di SQL Server 2016.
Kode demo di bawah. Perkiraan sangat dekat dalam kasus uji ini, tetapi akurasi bervariasi tergantung pada data.
Dalam kasus pengujian, di level compat 120, SQL Server tampaknya menggunakan histogram untuk estimasi, sedangkan di level compat 130 SQL Server tampaknya mengasumsikan 10% tetap dari tabel cocok.
CREATE DATABASE MyStringTestDB;
GO
USE MyStringTestDB;
GO
DROP TABLE IF EXISTS dbo.StringTest;
CREATE TABLE dbo.StringTest ( [TheString] varchar(15) );
GO
INSERT INTO dbo.StringTest
VALUES
( 'Y5_CLV' );
INSERT INTO dbo.StringTest
VALUES
( 'Y5_EG3' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_NE' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_PQT' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_T2V' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_TT4' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_ZKK' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_LW6' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_QO3' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_TZ7' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_UZZ' );
CREATE CLUSTERED INDEX IX_Clustered ON dbo.StringTest (TheString);
/*
Uses fixed % for estimate; 1.1 rows estimated in this case.
Plan for computation:
CSelCalcFixedFilter (0.1) <----
Selectivity: 0.1
*/
ALTER DATABASE MyStringTestDB SET compatibility_level = 130;
GO
SELECT *
FROM dbo.StringTest
WHERE SUBSTRING(TheString, 1, CHARINDEX('_',TheString) - 1) = 'ZZ'
OPTION (QUERYTRACEON 2363, QUERYTRACEON 3604);
/*
Uses histogram to get estimate of 1
CSelCalcPointPredsFreqBased <----
Distinct value calculation:
CDVCPlanLeaf
0 Multi-Column Stats, 1 Single-Column Stats, 0 Guesses
Individual selectivity calculations:
(none)
Loaded histogram for column QCOL: [DBA].[dbo].[StringTest].TheString from stats with id 1
*/
ALTER DATABASE MyStringTestDB SET compatibility_level = 120;
GO
SELECT *
FROM dbo.StringTest
WHERE SUBSTRING(TheString, 1, CHARINDEX('_',TheString) - 1) = 'ZZ'
OPTION (QUERYTRACEON 2363, QUERYTRACEON 3604);
/*
-- Simpler rewrite; works fine in both compat levels and gets better estimate.
SELECT *
FROM dbo.StringTest
WHERE TheString LIKE 'ZZ[_]%'
OPTION (QUERYTRACEON 2363, QUERYTRACEON 3604);
*/
Y5_EG3
string hanya kode dan huruf besar, maka Anda selalu dapat mencoba menentukan susunan biner -Latin1_General_100_BIN2
- yang seharusnya meningkatkan kecepatan pada operasi penyaringan. Cukup tambahkanCOLLATE Latin1_General_100_BIN2
keCREATE TABLE
pernyataan, tepat setelahvarchar(15)
. Saya akan penasaran untuk melihat apakah itu juga mempengaruhi pembuatan / estimasi rencana.