Có tài liệu hay nghiên cứu nào về các thay đổi trong SQL Server 2016 về cách ước tính cardinality cho các vị từ có chứa SUBSTRING () hoặc các hàm chuỗi khác không?
Lý do tôi hỏi là tôi đã xem xét một truy vấn có hiệu suất bị suy giảm trong chế độ tương thích 130 và lý do có liên quan đến sự thay đổi trong ước tính số lượng hàng khớp với mệnh đề WHERE có lệnh gọi SUBSTRING (). Tôi đã khắc phục sự cố bằng cách viết lại truy vấn, nhưng tôi tự hỏi liệu có ai biết bất kỳ tài liệu nào về các thay đổi trong lĩnh vực này trong SQL Server 2016 không.
Mã demo dưới đây. Các ước tính rất gần trong trường hợp thử nghiệm này, nhưng độ chính xác khác nhau tùy thuộc vào dữ liệu.
Trong trường hợp thử nghiệm, ở cấp độ compat 120, SQL Server dường như đang sử dụng biểu đồ cho ước tính, trong khi ở mức độ tương thích, 130 Server SQL dường như giả định 10% cố định của bảng khớp.
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
chuỗi chỉ là mã và luôn luôn viết hoa, thì bạn luôn có thể thử chỉ định đối chiếu nhị phân -Latin1_General_100_BIN2
- điều này sẽ cải thiện tốc độ của các hoạt động lọc. Chỉ cần thêmCOLLATE Latin1_General_100_BIN2
vào cácCREATE TABLE
tuyên bố, ngay sau khivarchar(15)
. Tôi sẽ tò mò xem liệu nó cũng ảnh hưởng đến việc tạo / ước tính kế hoạch.