Перетворення типу в виразі може вплинути на "CardinalityEstimate" у виборі плану запитів?


10

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

Ми обмежуємо події в кожній таблиці з обмеженням чека на стовпчик дати. Це дозволяє оптимізатору обмежувати таблиці, які шукаються за запитами, які фільтруються в стовпці дата події.

Назви обмежень перевірки генерували 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]. [Ім'я], 0)) може вплинути на "CardinalityEstimate" у виборі плану запитів

Що це означає в цьому контексті? Чи такий складний фільтр бентежить оптимізатор? Це щось, про що я повинен хвилюватися?


2
COLLATE Latin1_General_BIN2Робить вираз checks.nameunsargable. Що стосується конкретного запиту, не впевнений, наскільки, якщо якась різниця це внесе до оцінок кардинальності.
Мартін Сміт

2
Припускаючи , що двійковий файл COLLATEтільки там , щоб зробити вираз діапазону роботи правильно , ви могли б замінити N'[0-9A-F]')з N'[0123456789ABCDEF]'і падіннямCOLLATE Latin1_General_BIN2
Martin Smith

Відповіді:


16

Результат запиту здається правильним, і сервер його швидко виконує.

Але кореневий вузол плану виконання має попередження:

Перетворення типу в виразі (CONVERT_IMPLICIT (nvarchar (128), [o]. [Ім'я], 0)) може вплинути на "CardinalityEstimate" у виборі плану запитів

Що це означає в цьому контексті? Чи такий складний фільтр бентежить оптимізатор? Це щось, про що я повинен хвилюватися?

Попередження носить інформаційний характер. Якщо ваш запит виконувався повільно, або ви помітили, що оцінки кардинальності невірні, попередження дасть вам інформацію про те, де шукати можливу причину.

Попередження викликається неявною конверсією, яка використовується для зміни зіставлення. Якщо використання порівняння - це найпростіший спосіб отримати правильні результати, сміливо залишайте його таким, яким він є. Крім того, якщо ви поясните більше, чому це потрібно, хтось порадить вас.

Окрім того, REPLACEможна замінити на:

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

(Ця відповідь є резюме коментарів до питання.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.