Konwersja typu w wyrażeniu może wpływać na „CardinalityEstimate” w wyborze planu zapytań?

10

Prowadzę archiwalną bazę danych, która przechowuje dane historyczne w widokach podzielonym na partycje. Kolumna partycjonowania jest datetime. Każda tabela w widoku zawiera jeden miesiąc danych.

Ograniczamy zdarzenia w każdej tabeli ograniczeniem sprawdzania w kolumnie datetime. Dzięki temu optymalizator może ograniczyć tabele wyszukiwane w zapytaniach filtrujących kolumnę daty i godziny zdarzenia.

Nazwy ograniczeń sprawdzania zostały wygenerowane przez SQL Server, więc trudno jest wiedzieć, co robią, patrząc na ich nazwę.

Chcę, aby nazwy ograniczeń miały postać „CK_TableName_Partition”.

Mogę wygenerować skrypt zmiany nazwy za pomocą tego zapytania i kopiowania danych z kolumny sql_text. Klauzula WHERE pasuje do ograniczeń sprawdzania, których nazwy wyglądają tak, jakby zostały wygenerowane przez 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;

Dane wyjściowe wyglądają następująco:

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

Wynik zapytania wydaje się być poprawny, a serwer wykonuje go szybko.

Ale węzeł główny planu wykonania ma ostrzeżenie:

Konwersja typu w wyrażeniu (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) może mieć wpływ na „CardinalityEstimate” w wyborze planu zapytań

Co to znaczy w tym kontekście? Czy tak złożony filtr myli optymalizator? Czy to coś, o co powinienem się martwić?

Iain Samuel McLean Elder
źródło
2
To COLLATE Latin1_General_BIN2sprawia, że ​​wyrażenie na checks.namenieurządzalne. Jednak w przypadku konkretnego zapytania nie jest pewne, czy będzie to miało wpływ na szacunki liczności.
Martin Smith
2
Zakładając, że plik binarny COLLATEjest tylko tam, aby uczynić pracę ekspresji zakres poprawnie można zastąpić N'[0-9A-F]')z N'[0123456789ABCDEF]'i upuśćCOLLATE Latin1_General_BIN2
Martin Smith

Odpowiedzi:

16

Wynik zapytania wydaje się być poprawny, a serwer wykonuje go szybko.

Ale węzeł główny planu wykonania ma ostrzeżenie:

Konwersja typu w wyrażeniu (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) może mieć wpływ na „CardinalityEstimate” w wyborze planu zapytań

Co to znaczy w tym kontekście? Czy tak złożony filtr myli optymalizator? Czy to coś, o co powinienem się martwić?

Ostrzeżenie ma charakter informacyjny. Jeśli zapytanie zostało wykonane powoli lub zauważyłeś, że szacunki liczności były niepoprawne, ostrzeżenie poda informacje o tym, gdzie szukać możliwej przyczyny.

Ostrzeżenie jest wyzwalane przez niejawną konwersję zastosowaną do zmiany sortowania. Jeśli użycie sortowania jest najłatwiejszym sposobem na uzyskanie poprawnych wyników, pozostaw je bez zmian. Ewentualnie, jeśli wyjaśnisz więcej, dlaczego jest to potrzebne, ktoś Ci doradzi.

Nawiasem mówiąc, REPLACEmożna je zastąpić:

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

(Ta odpowiedź jest streszczeniem komentarzy do pytania).

Paul White 9
źródło