Как заставить запрос не использовать индекс в данной таблице?
В настоящее время я выполняю некоторые тесты для определения влияния производительности на включение индекса в заданный столбец в SQL Server 2005.
Набор тестовых данных, которые я использую, имеет приблизительно ~ 72 миллиона строк (около 6 ГБ данных). Чтобы действительно проверить производительность индекса, мне нужно иметь возможность сравнивать производительность с индексом и без него.
Это все хорошо и прекрасно, но создание индекса в первую очередь - не дешевая операция. Если я хочу проверить таблицу без индекса, мне нужно, по крайней мере, отключить индекс. Чтобы проверить с индексом, мне нужно снова включить его, что занимает довольно много времени.
Есть ли способ заставить SQL Server 2005 игнорировать данный индекс при выполнении запроса? Я не хочу отключать индекс только для проверки запроса, поскольку для отключения индекса требуется такое долгое время.
Ответы
Ответ 1
SELECT *
FROM MyTable WITH (INDEX(0))
WHERE MyIndexedColumn = 0
Запрос обычно будет использовать индекс в MyIndexedColumn, но из-за подсказки таблицы он будет вместо tablecan.
SELECT *
FROM MyTable WITH (INDEX(IndexName))
WHERE MyIndexedColumn = 0
Запрос обычно будет использовать индекс в MyIndexedColumn, но из-за подсказки таблицы вместо него будет использоваться индекс с именем IndexName.
Ответ 2
Я работаю со всеми различными типами БД и никогда не помню конкретный намек, когда мне это нужно. Поэтому я использую чистый SQL-подход, который (в настоящее время) работает со всеми БД, которые пересекают мой путь.
Идея состоит в том, чтобы сделать невозможным использование БД конкретным индексом путем обфускации соответствующего выражения в SQL. Например.
SELECT *
FROM MyTable
WHERE MyIndexedColumn + 0 = 0
Аналогично, вы можете добавить пустую строку к строковому значению. Текущие оптимизаторы не решают, что такие выражения не могут использовать индекс на (MyIndexedColumn)
.
На самом деле это анти-шаблон, описанный в моей книге. Вот некоторые из них на странице математика в SQL
Это окончательно достаточно для специального тестирования. В производственном коде подсказки более выразительны, конечно!
Ответ 3
Вы можете отключить индекс, который вы не хотите использовать в той же транзакции, в которой вы используете тестовый код, просто обязательно откат транзакции в конце. Это гарантирует, что тестовый код не будет использовать индекс, но предотвратит фактический отказ индекса.
BEGIN TRANSACTION
ALTER INDEX [MyIndex] ON MyTable DISABLE;
EXEC TestCode;
ROLLBACK
Это работает лучше, если у вас есть сложный случай, когда ваш тестовый код использует несколько индексов в разное время, и вы хотите проверить, улучшит ли добавление нового.