Запрос настроек 101
Не существует волшебной серебряной пули для настройки запросов, хотя я могу дать вам несколько советов и подсказок. Первое, что нужно сделать, это понять, что на самом деле происходит за кулисами. Получите хорошую внутреннюю книгу, например, «Путеводитель третьего гуру».
Плохо выполняющиеся запросы обычно бывают двух основных типов: транзакционные запросы, которые занимают слишком много времени, и шлифовальные пакетные задания (или отчеты), которые занимают слишком много времени. Один хороший признак запроса с чем-то не так - это один элемент в плане запроса, занимающий 99% времени.
Транзакционные запросы
В большинстве случаев плохо выполняемый транзакционный запрос является одной из нескольких вещей:
Отсутствующий индекс. Вы можете увидеть это в плане запроса - просмотр таблицы больших таблиц в соединении, который должен быть очень избирательным (т.е. возвращать несколько строк).
Запрос не может использовать индекс. Если у вас есть условия ИЛИ в предложении where, объединяет вычисленное значение или какой-либо другой элемент в запросе, который не может быть обработан с помощью sarg, то вам может потребоваться переписать запрос. Вкратце, sargs - это предикаты запросов, которые могут использовать индексы для удаления строк. Логическое «И», равенство и неравенство (>,> =, <, <= и! =) - все это может быть саргвируемым. ИЛИ традиционно не умеет саргить. Тем не менее, вы часто можете переводить OR в предикаты, пригодные для sarg, путем преобразования смысла из конструкций типа OR в NOT (foo и not bar).
Неэффективные предикаты. Например, если у вас есть where in
ссылка на вложенный подзапрос, посмотрите, можно ли его перезаписать как where exists
или как объединение. Это может привести к более эффективным планам запросов, и вот другие стандартные переписывания, которые вы также можете попробовать. Опять же, руководства Гуру и другие по этому вопросу являются хорошей отправной точкой.
Пакетные запросы
Пакетные запросы более сложны и имеют разные проблемы с настройкой. Некоторые советы:
Индексирование. Это может иметь большое значение по той же причине, что и для транзакционных запросов. Часто хорошим признаком отсутствия индекса является длительная операция шлифования (99% плана запроса), которая, кажется, не перебивает машину.
Временные столы. Возможно, вам будет удобнее разбить запрос на несколько запросов, заполняющих временные таблицы. Более крупные запросы дают оптимизатору больше возможностей для ошибок, хотя это не та проблема, которая была раньше. Создайте временные таблицы, так select into
как эта операция минимально регистрируется (намного меньше операций регистрации), что уменьшает нагрузку ввода-вывода.
Обратите внимание, что временные таблицы в базе данных tempdb имеют ту же структуру данных, которую оптимизатор использует для хранения промежуточных результатов объединения, поэтому за это не снижается производительность. Вы также можете создать индекс (включая кластеризованные и охватывающие индексы) для временной таблицы, что может повысить производительность запросов, читающих ее, по тем же причинам, по которым они улучшают запросы к статическим таблицам.
Не переусердствуйте с временными таблицами, так как они могут усложнить поиск по запросу. Для небольших таблиц в хранимой процедуре проверьте, помогают ли переменные таблицы. Это структура данных в памяти, поэтому они могут быть выигрышем в производительности.
Кластерные и покрывающие индексы. Это может повысить производительность запроса, поскольку они устанавливают локальность ссылок на диске на основе некоторого столбца группировки. Кластерный индекс может существенно повлиять на производительность пакетного задания.
Неэффективные предикаты. Это может вызвать проблемы с sargs и другими подоптимизациями во многом так же, как и с транзакционными запросами.
Таблица сканирования ваш друг. Вопреки распространенному мнению, сканирование таблицы не является по своей сути злом. Обычно они являются признаком чего-то неправильного в транзакционном запросе, но часто они являются наиболее эффективным способом выполнения крупномасштабной операции. Если вы делаете что-то с несколькими процентами строк в таблице, сканирование таблицы часто является наиболее эффективным способом покрытия таблицы.
Вложенные циклы включаются. Посмотрите, что оптимизатор делает с обеих сторон объединения. Это может быть неэффективно, если вы (например, таблица сканирует две большие таблицы по обе стороны от объединения вложенных циклов. Рассмотрите возможность использования кластерных индексов или order by
попыток изменить операцию на объединение слиянием или подсказку для продвижения хеш-объединения, если одна сторона достаточно маленький, чтобы сделать это с.
запирающий
Блокировка также может вызвать проблемы с производительностью. Если ваша система работает плохо под нагрузкой, посмотрите на профилировщик и счетчики perfmon, связанные с блокировками, и проверьте, есть ли какие-либо существенные конфликты. sp_who2
в результирующем наборе есть столбец BlkBy, который покажет, заблокирован ли запрос и что его блокирует. Кроме того, профили с событиями «граф взаимоблокировок» (если у вас есть запросы взаимоблокировки) и события, связанные с блокировкой, могут быть полезны для устранения проблем блокировки.
ConcernedOfTunbridgeWells
источник
Лучший совет: используйте SQL Server 2008 и запускайте монитор активности во время выполнения тестов. Обратите внимание на запросы, которые занимают больше всего времени / имеют наибольшее количество операций ввода-вывода и т. Д. Щелкните правой кнопкой мыши эти запросы, чтобы просмотреть запрос и / или план выполнения.
Далее: научиться понимать планы выполнения.
Далее: использовать мастер настройки базы данных.
Эти шаги помогут вам создать свои собственные "лучшие советы".
источник
Отличная свободно доступная электронная книга от RedGate о том, как работать и понимать планы выполнения SQL Server
http://www.red-gate.com/specials/Grant.htm?utm_content=Grant080623
Shameless затыкает, я ссылаться на настройки производительности материалы на моем блоге по SQL Server Performance .
Если у вас есть возможность переварить некоторые из этих материалов, пожалуйста, не стесняйтесь размещать их здесь или связываться со мной напрямую по конкретным вопросам.
источник
Во-первых, индексация. Многие люди не понимают, что внешние ключи не получают индексы автоматически. Поскольку они используются в соединениях, они почти всегда должны иметь индекс.
Внимательно изучите все курсоры, чтобы увидеть, могут ли они быть заменены кодом, основанным на множестве. Я изменил код, который работал от часов до секунд, делая это.
Избегайте подзапросов. Если они есть в коде, замените их соединениями или соединениями с производными таблицами.
Удостоверьтесь, что ваше предложение where является значимым.
Учитесь читать планы выполнения.
Убедитесь, что в офисе есть пара хороших книг по настройке производительности.
Табличные переменные лучше, чем временные таблицы в некоторых случаях, а временные таблицы работают лучше в других. Если вам нужно их использовать, попробуйте оба варианта и посмотрите, что работает лучше в данном конкретном случае.
источник