Преобразование типов в выражении может повлиять на «CardinalityEstimate» при выборе плана запроса?

10

Я поддерживаю архивную базу данных, которая хранит исторические данные в секционированных представлениях. Столбец разделения - это дата и время. Каждая таблица в представлении хранит данные за один месяц.

Мы ограничиваем события в каждой таблице проверочным ограничением в столбце datetime. Это позволяет оптимизатору ограничивать таблицы, в которых ищутся запросы, которые фильтруются по столбцу datetime события.

Имена проверочных ограничений были сгенерированы SQL Server, поэтому трудно понять, что они делают, посмотрев на их имя.

Я хочу, чтобы имена ограничений имели форму «CK_TableName_Partition».

Я могу создать сценарий переименования, используя этот запрос и копируя данные из столбца sql_text. Предложение WHERE соответствует проверочным ограничениям, имена которых выглядят так, как будто они были созданы 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]. [Name], 0)) может повлиять на «CardinalityEstimate» при выборе плана запроса

Что это значит в этом контексте? Неужели такой сложный фильтр сбивает с толку оптимизатор? Это то, что меня должно волновать?

Иэн Сэмюэл Маклин Старейшина
источник
2
Это COLLATE Latin1_General_BIN2делает выражение на checks.nameнеприемлемым. По вашему конкретному запросу не уверен, насколько сильно это повлияет на оценку количества элементов.
Мартин Смит,
2
Предполагая , что двоичный файл COLLATEтолько там , чтобы сделать выражение диапазона работы правильно , вы могли бы заменить N'[0-9A-F]')с N'[0123456789ABCDEF]'и падениемCOLLATE Latin1_General_BIN2
Martin Smith

Ответы:

16

Результат запроса кажется верным, и сервер выполняет его быстро.

Но у корневого узла плана выполнения есть предупреждение:

Преобразование типов в выражении (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) может повлиять на «CardinalityEstimate» при выборе плана запроса

Что это значит в этом контексте? Неужели такой сложный фильтр сбивает с толку оптимизатор? Это то, что меня должно волновать?

Предупреждение носит информационный характер. Если ваш запрос выполнялся медленно или вы заметили, что оценки количества элементов неверны, предупреждение даст вам информацию о том, где искать возможную причину.

Предупреждение вызывается неявным преобразованием, используемым для изменения параметров сортировки. Если использование сопоставления - это самый простой способ получить правильные результаты, не стесняйтесь оставить все как есть. В качестве альтернативы, если вы объясните больше, почему это необходимо, кто-то посоветует вам.

Кроме того, REPLACEможно заменить на:

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

(Этот ответ представляет собой краткое изложение комментариев к вопросу.)

Пол Уайт 9
источник