มีเอกสารหรืองานวิจัยใดเกี่ยวกับการเปลี่ยนแปลงใน SQL Server 2016 ถึงความคาดการณ์ของ cardinality สำหรับเพรดิเคตที่มี SUBSTRING () หรือฟังก์ชันสตริงอื่น ๆ หรือไม่?
เหตุผลที่ฉันถามคือฉันกำลังดูคิวรีที่ประสิทธิภาพลดลงในโหมดความเข้ากันได้ 130 และสาเหตุที่เกี่ยวข้องกับการเปลี่ยนแปลงในการประมาณจำนวนแถวที่ตรงกับส่วนคำสั่ง WHERE ที่มีการเรียกไปยัง SUBSTRING () ฉันแก้ไขปัญหาด้วยการเขียนแบบสอบถามใหม่ แต่สงสัยว่าถ้าใครรู้เรื่องเอกสารเกี่ยวกับการเปลี่ยนแปลงในพื้นที่นี้ใน SQL Server 2016
รหัสการสาธิตอยู่ด้านล่าง ค่าประมาณใกล้เคียงกันมากในกรณีทดสอบนี้ แต่ความแม่นยำนั้นขึ้นอยู่กับข้อมูล
ในกรณีทดสอบในระดับที่เข้ากันได้ 120, SQL Server ดูเหมือนจะใช้ฮิสโตแกรมสำหรับการประมาณการในขณะที่ในระดับที่เข้ากันได้ 130 SQL Server ดูเหมือนจะสมมติว่า 10% คงที่ของตารางที่ตรงกัน
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
สตริงเป็นเพียงรหัสและตัวพิมพ์ใหญ่คุณสามารถลองระบุการเปรียบเทียบไบนารีLatin1_General_100_BIN2
- ซึ่งควรปรับปรุงความเร็วในการกรอง เพียงแค่เพิ่มCOLLATE Latin1_General_100_BIN2
ไปยังคำสั่งหลังCREATE TABLE
varchar(15)
ฉันอยากรู้ว่ามันจะส่งผลกระทบต่อการสร้าง / การประมาณแผนหรือไม่