การแปลงประเภทในการแสดงออกอาจส่งผลกระทบต่อ "CardinalityEstimate" ในตัวเลือกแผนแบบสอบถาม?


10

ฉันรักษาฐานข้อมูลเก็บถาวรที่เก็บข้อมูลประวัติในมุมมองที่แบ่งพาร์ติชัน คอลัมน์แบ่งเป็นวันที่และเวลา แต่ละตารางใต้มุมมองจะเก็บข้อมูลหนึ่งเดือน

เรา จำกัด กิจกรรมในแต่ละตารางด้วยข้อ จำกัด การตรวจสอบในคอลัมน์วันที่และเวลา สิ่งนี้อนุญาตให้เครื่องมือเพิ่มประสิทธิภาพ จำกัด ตารางที่ค้นหาการสืบค้นที่กรองในคอลัมน์วันที่และเวลาของเหตุการณ์

ชื่อของข้อ จำกัด การตรวจสอบถูกสร้างขึ้นโดย SQL Server ดังนั้นจึงยากที่จะรู้ว่าสิ่งที่พวกเขาทำโดยดูที่ชื่อของพวกเขา

ฉันต้องการชื่อข้อ จำกัด ที่จะมีรูปแบบ 'CK_TableName_Partition'

ฉันสามารถสร้างสคริปต์การเปลี่ยนชื่อโดยใช้แบบสอบถามนี้และคัดลอกข้อมูลจากคอลัมน์ sql_text WHERE clause ตรงกับการตรวจสอบข้อ จำกัด ที่ชื่อดูเหมือนว่าถูกสร้างขึ้นโดย SQL Server:

SELECT
  checks.name AS check_name,
  tabs.name AS table_name,
  skemas.name AS schema_name,
  cols.name AS column_name,
  N'
EXECUTE sys.sp_rename
  @objname = N''' + skemas.name + N'.' + checks.name + N''',
  @newname = N''CK_' + tabs.name + N'_Partition'',
  @objtype = ''OBJECT'';' AS sql_text
FROM sys.check_constraints AS checks
INNER JOIN sys.tables AS tabs ON
  tabs.object_id = checks.parent_object_id
INNER JOIN sys.schemas AS skemas ON
  skemas.schema_id = tabs.schema_id
INNER JOIN sys.columns AS cols ON
  tabs.object_id = cols.object_id AND
  cols.column_id = checks.parent_column_id
WHERE checks.name LIKE (
  N'CK__' + SUBSTRING(tabs.name, 1, 9) +
  N'__' + SUBSTRING(cols.name, 1, 5) +
  N'__' + REPLACE(N'xxxxxxxx', N'x', N'[0-9A-F]') COLLATE Latin1_General_BIN2
)
ORDER BY table_name;

ผลลัพธ์มีลักษณะดังนี้:

check_name  table_name  schema_name column_name sql_text
CK__tbAcquisi__Acqui__5C4299A5  tbAcquisitions_201301   Archive AcquisitionDT   EXECUTE sys.sp_rename  @objname = N'Archive.CK__tbAcquisi__Acqui__5C4299A5',  @newname = N'CK_tbAcquisitions_201301_Partition',  @objtype = 'OBJECT';
CK__tbAcquisi__Acqui__76026BA8  tbAcquisitions_201302   Archive AcquisitionDT   EXECUTE sys.sp_rename  @objname = N'Archive.CK__tbAcquisi__Acqui__76026BA8',  @newname = N'CK_tbAcquisitions_201302_Partition',  @objtype = 'OBJECT';
CK__tbAcquisi__Acqui__7D6E8346  tbAcquisitions_201303   Archive AcquisitionDT   EXECUTE sys.sp_rename  @objname = N'Archive.CK__tbAcquisi__Acqui__7D6E8346',  @newname = N'CK_tbAcquisitions_201303_Partition',  @objtype = 'OBJECT';
...
CK__tbRequest__Reque__60132A89  tbRequests_201301   Archive RequestDT   EXECUTE sys.sp_rename  @objname = N'Archive.CK__tbRequest__Reque__60132A89',  @newname = N'CK_tbRequests_201301_Partition',  @objtype = 'OBJECT';
CK__tbRequest__Reque__1392CE8F  tbRequests_201302   Archive RequestDT   EXECUTE sys.sp_rename  @objname = N'Archive.CK__tbRequest__Reque__1392CE8F',  @newname = N'CK_tbRequests_201302_Partition',  @objtype = 'OBJECT';
CK__tbRequest__Reque__1AFEE62D  tbRequests_201303   Archive RequestDT   EXECUTE sys.sp_rename  @objname = N'Archive.CK__tbRequest__Reque__1AFEE62D',  @newname = N'CK_tbRequests_201303_Partition',  @objtype = 'OBJECT';

ดูเหมือนว่าผลลัพธ์ของแบบสอบถามจะถูกต้องและเซิร์ฟเวอร์จะดำเนินการอย่างรวดเร็ว

แต่โหนดรูทของแผนการดำเนินการมีคำเตือน:

การแปลงประเภทในนิพจน์ (CONVERT_IMPLICIT (nvarchar (128), [o]. [ชื่อ], 0)) อาจส่งผลต่อ "CardinalityEstimate" ในตัวเลือกแผนแบบสอบถาม

สิ่งนี้หมายความว่าอย่างไรในบริบทนี้ ตัวกรองที่ซับซ้อนเช่นนี้ทำให้เครื่องมือเพิ่มประสิทธิภาพสับสนหรือไม่ มันเป็นสิ่งที่ฉันควรกังวลเกี่ยวกับ?


2
COLLATE Latin1_General_BIN2ทำให้การแสดงออกบนchecks.nameunsargable สำหรับคำค้นหาที่เฉพาะเจาะจงของคุณไม่แน่ใจว่ามีความแตกต่างมากน้อยเพียงใดที่จะเกิดขึ้นกับการประเมินความเป็นหัวใจของ cardinality
Martin Smith

2
สมมติว่าไบนารีCOLLATEอยู่ที่นั่นเท่านั้นเพื่อให้การแสดงออกของช่วงทำงานได้อย่างถูกต้องคุณสามารถแทนที่N'[0-9A-F]')ด้วยN'[0123456789ABCDEF]'และปล่อยCOLLATE Latin1_General_BIN2
Martin Smith

คำตอบ:


16

ดูเหมือนว่าผลลัพธ์ของแบบสอบถามจะถูกต้องและเซิร์ฟเวอร์จะดำเนินการอย่างรวดเร็ว

แต่โหนดรูทของแผนการดำเนินการมีคำเตือน:

การแปลงประเภทในนิพจน์ (CONVERT_IMPLICIT (nvarchar (128), [o]. [ชื่อ], 0)) อาจส่งผลต่อ "CardinalityEstimate" ในตัวเลือกแผนแบบสอบถาม

สิ่งนี้หมายความว่าอย่างไรในบริบทนี้ ตัวกรองที่ซับซ้อนเช่นนี้ทำให้เครื่องมือเพิ่มประสิทธิภาพสับสนหรือไม่ มันเป็นสิ่งที่ฉันควรกังวลเกี่ยวกับ?

คำเตือนเป็นข้อมูล หากการค้นหาของคุณดำเนินการช้าหรือคุณสังเกตเห็นว่าการประมาณค่า cardinality ไม่ถูกต้องคำเตือนจะให้ข้อมูลเกี่ยวกับสาเหตุที่เป็นไปได้

คำเตือนถูกกระตุ้นโดยการแปลงโดยนัยที่ใช้สำหรับการเปลี่ยนการเรียง หากใช้การเปรียบเทียบเป็นวิธีที่ง่ายที่สุดในการรับผลลัพธ์ที่ถูกต้องอย่าลังเลที่จะทิ้งไว้เหมือนเดิม อีกทางเลือกหนึ่งถ้าคุณอธิบายเพิ่มเติมเกี่ยวกับสาเหตุที่มีความจำเป็น

นอกจากREPLACEจะสามารถแทนที่ด้วย:

REPLICATE(N'[0-9A-F]', 8);

(คำตอบนี้เป็นบทสรุปของความคิดเห็นต่อคำถาม)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.