В очередной раз хочу напомнить про простые и в тоже время важные вещи:
- необходимость правильного проектирования структуры таблиц и индексов (с учётом планируемого использования и, что немаловажно, ожидаемого роста количества данных);
- необходимость периодической проверки актуальности и использования уже созданных индексов и, главное, регулярный анализ списка "тяжёлых"/ресурсоёмких запросов (хотя бы через стандартные средства MS SQL).
Некоторое время назад, при "дежурном" осмотре параметров работы MS SQL-сервера, моё внимание привлёк один из таких "тяжёлых" запросов.
Анализ ситуации показал, что из таблицы с более чем 25 млн. записей/строк регулярно выбирались данные отфильтрованные по значению одного поля. И хотя в результирующей выборке было всего около 3-5 записей, запрос выполнялся довольно долго, а также попал в список "тяжелых", так как индекса по этому полю не было и каждый раз происходило сканирование всей таблицы.
В итоге, после добавления индекса по этому полю, данный запрос стал выполняться практически мгновенно, исчез из списка тяжёлых запросов, и, главное, перестал впустую нагружать сервер.
К сожалению, за всё в этом мире надо платить. В этот раз пришлось пожертвовать дисковым пространством - индекс занял примерно треть исходного объема таблицы, а также появились накладные расходы на поддержание этого индекса при вставке и обновлении записей. В этот раз я посчитал эти расходы допустимыми, но каждый раз надо внимательно анализировать текущую ситуацию.
PS И ещё один случай - таблица с почти 3,5 млн. строк. Запросом выбирается одна (TOP 1) строка по значениям трёх полей (одно из которых "дата"). Ранее были созданы отдельные индексы практически на все поля этой таблицы (здесь можно и даже нужно вспомнить про понятие селективности индекса и, соответственно, его эффективности для, например, битовых полей). В результате вместо использования существующих индексов каждый раз идёт практически полный перебор. Как решение в данном случае создал один индекс из этих трёх полей, но без включения доп. полей (include), чтобы излишне не раздувать его размер.