|
|
|||||||||||||||||||||||||||||
|
Общий план оптимизации и настройки запросов SQL ServerИсточник: SQL exercises
Во время недавнего собеседования, которое я проходил, чтобы найти новую работу прежде, чем закончится мой текущий контракт, мне задали вопрос, который захватил меня врасплох. Интервьюер просто спросил меня, какие шаги я бы предпринял, чтобы выяснить, какие хранимые процедуры нуждаются в оптимизации, и что я обычно делаю для оптимизации запросов. Меня застал врасплох не сам вопрос; а осознание того, что я не имел "формального" плана действий для определения того, какие хранимые процедуры нуждаются в оптимизации, или плана для их фактической оптимизации. После собеседования я решил формализовать основные действия, которые имел обыкновение предпринимать для нахождения хранимых процедур, нуждающихся в оптимизации и действий, которые необходимы в случае, если запрос требует оптимизации. После записи некоторых заметок, я решил, что следует сделать из этого "плана" статью, чтобы и другие знали, какие основные шаги необходимы для оптимизации запроса. Как вы уже догадались, первый шаг, который следует сделать, заключается в идентификации запросов, нуждающихся в настройке. По существу имеется два типа запросов в инсталляции SQL Server: запросы до внедрения и после внедрения. Само собой разумеется, что все новые (до внедрения) запросы должны быть полностью оптимизированы даже прежде, чем вы соберетесь их внедрять. Однако запросы, которые были уже внедрены, даже те, которые вы уже оптимизировали, должны пересматриваться при изменении состояния базы данных, чтобы узнать, не создают ли они новых проблем. Большинство компаний обычно работают только с запросами после внедрения, когда они создают проблему и помещаются в список "багов" некоторого типа. Да, вы можете обнаружить проблемные запросы таким способом, но если вы будете дожидаться, пока они не появятся в списке "багов", вы попадете в цейтнот, "фиксируя" проблему, делая резервную копию приложения и запуская его. Если повезет, то вам хватит времени, чтобы применить новые знания по настройке производительности, которые вы приобрели за время, прошедшее с момента, когда в последний раз работали над запросом при решении новой проблемы. Этот способ настройки запросов по факту может позволить, а может и не позволить вам идентифицировать и исправить ключевой момент потери производительности ваших хранимых процедур, поскольку он имеет дело с теми запросами, которые настолько плохи, что привлекают к себе основное внимание. Лучший план позволил бы вам не только работать над проблемными запросами по мере их появления, но и получить списки запросов, которые демонстрируют проблемную производительность до того, как они попадают в список "багов". Тогда эти запросы могут оптимизироваться, когда у вас есть на это время или когда вы адаптируете их к новой версии приложения. Использование мощности SQL Profiler и выполнение простой трассировки для определения производительности ваших хранимых процедур может облегчить получение этих новых списков запросов. Такую трассировку просто создать, и, в зависимости от установки, запускать в моменты максимальной и минимальной загрузки в течение нескольких дней, чтобы получить хорошую выборку данных. Создание списка запросов с помощью трассировки SQL ProfilerЧтобы получить списки запросов, вам потребуется создать и выполнить трассировку, фиксирующую все события хранимой процедуры, а также следующие столбцы данных: - EventClass Такая трассировка может породить большое количество данных, поэтому может оказаться проще сделать так, чтобы информация помещалась в таблицу, из которой вы сможете извлекать ее с помощью запроса. Если можно найти способ фильтровать трассу, чтобы ограничить вывод данных, я предложил бы вам это сделать. Я обычно использую для имен моих хранимых процедур префикс 'spXXXX', поэтому я могу выполнить фильтрацию по имени объекта. Но поскольку вы работаете с уже имеющейся ситуацией, приходится что-то придумать, чтобы, допуская фильтрацию некоторых ненужных данных, получить необходимые данные и уменьшить трассу. Теперь, когда вы сохранили ваши данные в таблице, создайте хранимые процедуры, которые выдадут самые плохие по производительности процедуры, учитывая длительность (длительность выводится в миллисекундах), SP:CacheMiss (отсутствие в кэше), SP:Recompile (перекомпиляция), Reads (чтения) и Write (записи). Создайте списки с наибольшими длительностями, наибольшим числом чтений, наибольшим числом записей и хранимыми процедурами, которые включают события SP:CacheMiss и SP:Recompile. Возможно, вам потребуется несколько попыток, чтобы понять, какое число операций чтения и записи считается чрезмерным в вашей базе данных, но если вы видите хранимую процедуру, которая превышает среднее значение этих показателей, с нее можно начать. Остальные списки проще для определения проблемных запросов, на которые можно воздействовать сразу. Теперь, когда вы получили свои списки запросов, подлежащих переработке, - долго выполняющиеся запросы, запросы с чрезмерным числом чтений и записей, запросы, которые перекомпилируются, - что нужно делать, чтобы оптимизировать их? Долго выполняющиеся и новые запросыПервое, что нужно сделать для длительно выполняющихся запросов и запросов, которые вы только что создали, это получить их план выполнения. Используя план выполнения, вы должны: - Найти то, что окрашено красным цветом. Анализатор запросов (Query Analyzer) окрасит значки красным, если определит, что там есть определенные проблемы. Обычно красный цвет означает, что статистические данные индексов, используемых данной частью запроса, устарели, однако, это может означать и другие вещи. Обращайте внимание на любые значки, которые имеют красный цвет, и думайте, как устранить проблемы. Если вы находите сегменты кода, которые кажутся более длительными, чем должны бы быть, используйте следующий список, чтобы пробовать определить что не так в этом сегменте. Вы должны также использовать этот список, чтобы оптимизировать весь ваш код вообще, даже если этот код, возможно, не выглядит проблемным.
Перекомпиляция запросовДаже если вы оптимизировали запросы, анализируя план выполнения и код, вы все еще можете иметь проблему, которую огромное большинство разработчиков даже не рассматривает. Эта проблема - стоимость работы, выполняемая всякий раз, когда для запроса должен быть создан новый план или выполнена повторная компиляция. Обычно повторной компиляции легко избежать, что дает значительный прирост производительности многих приложений. Следует иметь в виду, когда вы получаете список перекомпилирующихся хранимых процедур, что есть законные причины для того, чтобы перекомпилировать хранимые процедуры. Поэтому вы должны побеспокоиться в первую очередь о тех из них, для которых компиляция выполняется при каждом их исполнении. Другими вы можете заняться позже, решая, требуется ли для них перекомпиляция или нет.
Итак, вы изучили план выполнения, проанализировали код и выявили повторную компиляцию; что теперь? Лишь только то, что все выглядит прекрасно, еще не означает, что запрос будет удовлетворительно выполняться в каждом отдельном сценарии. Вы должны придумать различные тесты для вашего запроса. Как он выполняется на наборах данных различного объема? Как он выполняется с различными наборами параметров? Что будет, если вы запустите запрос многократно, используя многочисленные соединения в Query Analyzer? Что бы вы ни думали о своем конкретном случае, требуется выполнять трассировку и анализ. Только не говорите: "Я настроил этот запрос, и он готов", - если вы запустили его только один раз. Проявите твердость и убедите ваших клиентов и менеджеров, что вам нужно время, чтобы полностью проверить новый или недавно переработанный запрос. Это более важно, чем быстрая установка заплаток, чтобы только выполнить работу в срок. Как было сказано, это только общий план. Добавьте в него любые новые пункты, которые пришли вам в голову. Расширьте мои этапы своими наработками, накопленными за годы, и решениями общих проблем, которые вы обнаружили в своей базе данных. Как бы вы ни решили оптимизировать ваши запросы, запишите это, чтобы у вас было нечто "формальное", что можно передать другим в вашей группе или просто использовать, чтобы дать ответы на вопрос интервью, который захватил меня врасплох, если вам это когда нибудь понадобится. Randy Dyess (оригинал: An Introduction to SQL Server Query Tuning)
|
|