Jenis konversi dalam ekspresi dapat memengaruhi “CardinalityEstimate” dalam pilihan paket kueri?

10

Saya memelihara database arsip yang menyimpan data historis dalam tampilan yang dipartisi. Kolom partisi adalah datetime. Setiap tabel di bawah tampilan menyimpan satu bulan data.

Kami membatasi acara di setiap tabel dengan tanda centang centang pada kolom datetime. Ini memungkinkan pengoptimal untuk membatasi tabel yang dicari untuk pertanyaan yang memfilter pada kolom datetime acara.

Nama-nama kendala pemeriksaan dihasilkan oleh SQL Server, jadi sulit untuk mengetahui apa yang mereka lakukan dengan melihat nama mereka.

Saya ingin nama kendala memiliki bentuk 'CK_TableName_Partition'.

Saya dapat membuat skrip rename menggunakan kueri ini dan menyalin data dari dari kolom sql_text. Klausa WHERE cocok dengan kendala periksa yang namanya dibuat oleh 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;

Outputnya terlihat seperti ini:

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';

Hasil kueri tampaknya benar dan server mengeksekusinya dengan cepat.

Tetapi simpul akar dari rencana eksekusi memiliki peringatan:

Ketik konversi dalam ekspresi (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) dapat memengaruhi "CardinalityEstimate" dalam pilihan rencana kueri

Apa artinya itu dalam konteks ini? Apakah filter yang sedemikian rumit membingungkan pengoptimal? Apakah ini sesuatu yang harus saya khawatirkan?

Iain Samuel McLean Elder
sumber
2
The COLLATE Latin1_General_BIN2membuat ekspresi di checks.nameunsargable. Untuk permintaan spesifik Anda tidak yakin berapa banyak jika ada perbedaan yang akan terjadi pada perkiraan kardinalitas.
Martin Smith
2
Dengan asumsi biner COLLATEhanya ada untuk membuat ekspresi rentang berfungsi dengan benar, Anda dapat menggantinya N'[0-9A-F]')dengan N'[0123456789ABCDEF]'dan menjatuhkanCOLLATE Latin1_General_BIN2
Martin Smith

Jawaban:

16

Hasil kueri tampaknya benar dan server mengeksekusinya dengan cepat.

Tetapi simpul akar dari rencana eksekusi memiliki peringatan:

Ketik konversi dalam ekspresi (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) dapat memengaruhi "CardinalityEstimate" dalam pilihan rencana kueri

Apa artinya itu dalam konteks ini? Apakah filter yang sedemikian rumit membingungkan pengoptimal? Apakah ini sesuatu yang harus saya khawatirkan?

Peringatan itu bersifat informasi. Jika kueri Anda berkinerja lambat, atau Anda melihat bahwa perkiraan kardinalitas salah, peringatan itu akan memberi Anda informasi tentang ke mana harus mencari kemungkinan penyebabnya.

Peringatan dipicu oleh konversi implisit yang digunakan untuk perubahan susunan. Jika menggunakan susunan adalah cara termudah untuk mendapatkan hasil yang benar, jangan ragu untuk membiarkannya apa adanya. Atau, jika Anda menjelaskan lebih lanjut mengapa itu diperlukan, seseorang akan memberi tahu Anda.

Selain itu, REPLACEdapat diganti dengan:

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

(Jawaban ini adalah ringkasan komentar untuk pertanyaan.)

Paul White 9
sumber