Skip to content

SARGability: что это вообще такое?

Пересказ статьи Erik Darling. SARGability Week What Is It, Anyway?


Возможность SARG - это способ сказать, что поисковые предикаты могут использоваться для поиска по ключам индекса.

Вот некоторые вещи, препятствующие этому:

  • функция(столбец) = что-то

  • столбец + столбец = что-то

  • столбец + значение = что-то

  • значение + столбец = что-то

  • столбец = @что-то или @что-то IS NULL

  • столбец like '%что-то'

  • столбец = case when...

  • значение = case when столбец...

  • Несоответствие типов данных

Да, об этом много писалось повсюду, но есть шаблон запроса, на исправление которого я все еще трачу много времени.

Итак, снова об этом.

Если вам надоело об этом слышать, перестаньте это делать.

Симптомы


Скажем, у нас имеется следующая таблица:

CREATE TABLE
dbo.sargability
(
id int PRIMARY KEY,
start_date date,
end_date date
);

Сейчас для этой таблицы есть только один индекс на столбце id. Поскольку это кластеризованный индекс (по умолчанию ввиду первичного ключа), он также "включает" столбцы start_date и end_date. С другой стороны, это также означает, что в любой некластеризованный индекс, который мы создаем, будет автоматически добавляться столбец id. В случае неуникального индекса он будет добавлен в ключ. В случае уникального индекса он будет находиться в "include".

Однажды кто-то спорил со мной об этом последнем пункте, настаивая, что кластеризованный индекс не включает все столбцы таблицы. Но вы знаете, что если мы выполним этот запрос, мы обращаемся только к кластеризованному индексу:

SELECT
s.start_date,
s.end_date
FROM dbo.sargability AS s;



Скользкий


Это означает две вещи: пока мы избегаем подобных ошибок в суждениях, мы можем искать отдельное значение или диапазон значений в столбце id. Индекс содержит упорядоченные данные (в данном случае по возрастанию).

Это также означает, что start_date и end_date не упорядочены, поэтому любой наш запрос, который пытается найти/отфильтровать там значения, будет сканировать индекс (если мы так же не ищем/фильтруем столбец id).

SELECT
s.start_date,
s.end_date
FROM dbo.sargability AS s
WHERE id = 1;

SELECT
s.start_date,
s.end_date
FROM dbo.sargability AS s
WHERE s.start_date = '20210808';

SELECT
s.start_date,
s.end_date
FROM dbo.sargability AS s
WHERE s.end_date = '20210808';



Переделка


Несмотря на то, что предикат равенства на start_date и end_date является совершенно поисковым (SARGable), для них нет индекса, чтобы выполнить поиск нужных значений. Имеется только кластеризованный индекс, который упорядочен по столбцу id. Другие столбцы не имеют полезного порядка.

Тот факт, что оба запроса завершаются сканированием кластеризованного индекса, может создать у вас впечатление, что приемлема версия с isnull.

SELECT
s.start_date,
s.end_date
FROM dbo.sargability AS s
WHERE s.end_date = '20210808';

SELECT
s.start_date,
s.end_date
FROM dbo.sargability AS s
WHERE ISNULL(s.end_date, '19000101') = '20210808';

Однако при наличии индекса на столбце проблема становится более очевидной, с "хорошим" поисковым запросом и "плохим" сканирующим.

CREATE INDEX s ON dbo.sargability(end_date) INCLUDE(start_date);



В следующий раз мы рассмотрим различные способы исправления не-SARGable запросов посредством таких вещей, как вычисляемые столбцы, временные таблицы, порядок ключевых столбцов индекса и динамического SQL.

Это те подходы, которые я обычно использую в моей работе по настройке запросов, поэтому надеюсь, что и вы сочтете их полезными.

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Автор не разрешил комментировать эту запись

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.