Что делает оператор SQL саргным? - PullRequest
231 голосов
/ 28 апреля 2009

По определению (по крайней мере из того, что я видел) sargable означает, что запрос способен заставить механизм запросов оптимизировать план выполнения, который использует запрос. Я пытался найти ответы, но, кажется, не так много по теме. Итак, вопрос в том, что делает или не делает SQL-запрос саргным? Любая документация будет принята с благодарностью.

Для справки: SARGable

Ответы [ 4 ]

232 голосов
/ 29 апреля 2009

Самая распространенная вещь, которая делает запрос non-sargable - это включение поля внутри функции в предложении where:

SELECT ... FROM ...
WHERE Year(myDate) = 2008

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

WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009'

Некоторые другие примеры:

Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones'
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))

Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford'
Fixed: Select ... WHERE DealerName Like 'Ford%'

Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate()) 
75 голосов
/ 29 апреля 2009

Не делайте этого:

WHERE Field LIKE '%blah%'

Это вызывает сканирование таблицы / индекса, поскольку значение LIKE начинается с символа подстановки.

Не делайте этого:

WHERE FUNCTION(Field) = 'BLAH'

Это вызывает сканирование таблицы / индекса.

Сервер базы данных должен будет сравнить FUNCTION () с каждой строкой таблицы, а затем сравнить ее с BLAH.

Если возможно, сделайте все наоборот:

WHERE Field = INVERSE_FUNCTION('BLAH')

Это запустит INVERSE_FUNCTION () для параметра один раз и все еще позволит использовать индекс.

9 голосов
/ 29 апреля 2009

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

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

Таким образом, кроме всего прочего, оператор SQL более уместен, когда оптимизатор ожидает, что число результирующих строк в одной таблице будет меньше, чем переломный момент возможного индекса в следующей таблице.

Подробный пост и пример вы можете найти здесь .

3 голосов
/ 10 июня 2017

Чтобы операция считалась пригодной для выполнения, недостаточно просто иметь возможность использовать существующий индекс. В приведенном выше примере добавление вызова функции к индексируемому столбцу в предложении where, скорее всего, по-прежнему использует некоторые преимущества определенного индекса. Он будет «сканировать» или извлекать все значения из этого столбца (индекса), а затем удаляет те, которые не соответствуют предоставленному значению фильтра. Это все еще недостаточно эффективно для таблиц с большим количеством строк. Что действительно определяет sargability, так это возможность запроса обходить индекс b-дерева, используя метод двоичного поиска, который основывается на исключении половины набора для массива отсортированных элементов. В SQL это будет отображаться в плане выполнения как «поиск по индексу».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...