Skip to content

Введение в хранилище запросов SQL Server

Пересказ статьи MATTHEW MCGIFFEN. Introduction to SQL Server Query Store


Появление в SQL 2016 Query Store (хранилище запросов) явилось, без сомнения, наиболее привлекательной и обсуждаемой новой функциональностью. В этой статье мы просто бросим краткий взгляд на нее, что это такое, как запустить и как это можно использовать. Это будет довольно краткий обзор - потребуется целая книга, чтобы описать все подробно - но, надеюсь, что он даст вам понятие о том, насколько это будет полезно и как начать использовать.
На базовом уровне то, что делает хранилище запросов, довольно просто. Оно просто хранит информацию, относящуюся к исполняющимся запросам.

Эта информация состоит из двух вещей:

  • Планы выполнения - планы выполнения, генерируемые для каждого запроса, сохраняются в хранилище запросов, и, если план меняется, новый план сохраняется тоже.

  • Метрики производительности - такая информация, как использование ЦП, чтения и записи, захватывается и сохраняется для каждого запроса.

Эта информация агрегируется по интервалам (по умолчанию 1 час), поэтому вы можете видеть, как меняется производительность запроса с течением времени.

Это не что-то радикально новое, вы уже могли выполнить запрос для нахождения плана выполнения запроса, и вы также могли запросить агрегированные метрики производительности, относящиеся к заданному запросу.

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

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

Обычной причиной этого является то, что называется "регрессией плана". Это когда план выполнения изменился - а новый план не так хорош, как старый, для большего числа выполнений. Раньше вы могли подозревать, что именно это было причиной наблюдаемой проблемы, но не было легкого способа проверить это. Теперь вы можете использовать хранилище запросов для наблюдения и сравнения старого и нового планов, чтобы проверить это. Вы можете даже одним или двумя щелчками заставить запрос вернуться к использованию старого (лучшего) плана - хотя мы надеемся, что люди не будут злоупотреблять этой возможностью, а попытаются, по крайней мере, разобраться в проблеме и подумать о ее решении. Обычно существует причина, по которой SQL считает, что новый план будет лучше - и конкретный план может хорошо работать на данный момент, но он может оказаться не лучшим планом в будущем, когда данные поменяются.

Давайте рассмотрим эту функциональность немного более подробно.

Включение хранилища запросов


Хранилище запросов - это конфигурация уровня базы данных. Важно понимать это и то, что информация фактически хранится в системных таблицах базы данных. Это означает, что если вы резервируете и восстанавливаете базу данных, информация сохраняется. Очень важно также, что информация сохраняется асинхронно - поэтому не должно быть какого-либо влияния на производительность при выполнении самих запросов. Конечно, будут иметь место некоторые накладные расходы сервера в момент сохранения данных, но в большинстве случаев незначительные.

Вы можете включить Query Store для базы данных с помощью T-SQL (или в вашем исходном коде) или посредством GUI в SSMS. Я просто хочу продемонстрировать это в GUI, чтобы вы смогли увидеть разные опции. Выполните щелчок правой кнопкой на базе данных, выберите свойства, а затем выберите страницу Query Store в самом низу списка:



Как видно выше, Query Store включен для базы данных WideWorldImporters со всеми установками по умолчанию.

Первой установкой является “Operation Mode”. По умолчанию она установлена в "Off". Чтобы включить Query Store и позволить ему выполняться для конкретной базы данных, вам следует изменить ее на “Read Write”. Это все.

Интервал Data Flush - это как часто данные хранилища запросов записываются на диск - напомню, что это выполняется асинхронно.

Интервал Statistics Collection задает величину отрезков времени, в которых агрегируются метрики производительности запроса.

Затем у нас есть кое-что, связанное с хранением данных. Важно отметить, что если хранилище запросов заполнится и ничто не приведет к его очистке, то оно перейдет в режим Read-Only (только чтение), и никакие данные не будут сохраняться, пока не освободится место. По умолчанию объем установлен в 100Мб - это не так много места, поэтому я реально не вижу никаких оснований не включать эту функцию.

Оставляя установку Auto для “Size Based Cleanup Mode”, должно гарантировать, что старые данные очищаются, если хранилище запросов начнет заполняться. Выше находится “Query Store Capture Mode” - если оставить AUTO, то будут игнорироваться нечастые запросы или запросы с незначительными накладными расходами.

Последняя настройка “Stale Query Threshold” определяет то, как долго хранятся данные в днях. 30 дней принимается по умолчанию. Было бы полезно существенно увеличить ее, если мы хотим использовать Query Store для мониторинга производительности на более длительный период. Но это может зависеть от места, которое хранилище запросов будет использовать для вашей базы данных - помните, что значением по умолчанию является 100Мб, но вы можете увеличить его, когда захотите.

Внизу страницы свойств можно увидеть несколько круговых диаграмм, которые показывают сколько места в базе данных выделено Query Store и сколько из этого места использовано.

Итак, хранилище запросов установлено и сконфигурировано, давайте посмотрим на то, что это нам дает.

Хранилище запросов в действии и навязывание плана


Как показано выше, я установил Query Store для копии базы данных WideWorldImporters на экземпляре SQL 2016. Я создал хранимую процедуру, которую запускаю каждые 2 секунды, и установил 1-минутный интервал Statistics Collection Interval в Query Store (а не 1 час) с тем, чтобы довольно быстро получить некоторые цифры и графики.

В ветке базы данных в SSMS теперь появилась папка Query Store, где находятся некоторые встроенные отчеты:



Для этого сообщения в блоге я собираюсь продемонстрировать только пару из них. Давайте откроем отчет “Top Resource Consuming Queries”:



Можно увидеть несколько вещей. Слева вверху находится гистограмма наиболее дорогих запросов (вы видите один большой прямоугольник, а остальные небольшие по сравнению с ним - большой соответствует моему запросу). Вы можете задать в конфигурации затраты ЦП или логические чтения среди других опций, а также нужны ли вам средние, максимальные или минимальные значения. По сути, есть масса способов, которыми вы можете настроить свое представление.

Честно говоря, я боролся с некоторыми из этих встроенных отчетов Query Store, чтобы заставить их показать мне то, что я хотел, поэтому готовьтесь немного поиграть, чтобы понять, как использовать эту функцию.

На гистограмме зеленый прямоугольник - это выбранный в настоящее время запрос, справа находится точечный график показателей выполнения этого запроса на интервалах нашей статистики (напомню, что я установил интервал в 1 минуту). Можно видеть, что я наблюдаю среднее число логических чтений. Вы также видите, что этот запрос прекрасно выполнялся примерно до 14:05, когда что-то произошло (это был я!) и число логических чтений в каждом выполнении внезапно выросло. Кружки на точечном графике в этом месте также изменили цвет, и это показывает, что теперь запрос использует новый план выполнения.

Рядом с графиком находится легенда, сообщающая какому плану соответствует цвет кружка, и, если вы щелкните на желаемом плане в легенде, он отобразится на нижней панели. В данный момент я наблюдаю исходный план (Plan 1). Заметим, что в заголовке указано "not forced" (не навязанный), также имеется кнопка справа от заголовка, предлагающая вариант "Force Plan" (навязанный план). Давайте задержимся на минуту, прежде чем сделаем это.

Прежде чем что-то поменять, чтобы попытаться решить проблему с этим запросом, давайте посмотрим отчет “Regressed Queries”. Он почти такой же, но вы можете использовать его с разных сторон. Т.е. он может не быть одним из наиболее дорогих ваших запросов, которые начали работать плохо, поэтому, если вы взгляните на отчет Regressed Queries, он будет фокусироваться на тех запросах, для которых план выполнения изменился в интервале, который вы рассматриваете. И опять для меня было непросто добиться от этого отчета, чтобы он дал интересующую меня информацию - потребуется немного поиграться с ним.



Вы можете увидеть на диаграмме только один большой широкий прямоугольник - т.к. я имею только один регрессивный запрос с интервале (последние 30 минут), который я выбрал для просмотра. Это может упростить выявление запросов, в которых возникает подобная проблема.

Я вернусь к предыдущему отчету Resource Consumers (потребление ресурсов) и попытаюсь решить проблему. Теперь я действительно знаю, что я делал и почему запрос стал плохим. Это был результат, вызванный прослушиванием параметров, когда, если перекомпилировать хранимую процедуру, сформированный план выполнения может отличаться в зависимости от параметров, с которыми выполнялся запрос. Обычно это формирует лучший план для предоставленных параметров - но может оказаться далеко не лучшим планом для всех наборов параметров. В данном случае я принудил хранимую процедуру сформировать план, который оказался дорогим в большинстве случаев.

Эту проблему было бы лучше пофиксить в коде хранимой процедуры, но в продакшене исправление может занять несколько дней, а у нас есть проблема прямо сейчас. Поэтому давайте использовать функциональность Force Plan для решения проблемы - только на время.

Я выбираю желаемый план и щелкаю кнопку “Force Plan”. Эффект проявляется сразу, и я замечаю его спустя минуты, поскольку мой интервал сбора статистики очень мал. Пусть поработает немного, и я покажу вам новый график:



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

Сравнение планов


Связанной функцией в SQL 2016 является возможность сравнения двух планов выполнения для поиска изменений. Для себя я не посчитал это удивительным, когда посмотрел на нее, но это было обусловлено естественными ограничениями — если два плана существенно отличаются, то выделение различия просто выделит все. Однако это может быть полезным, чтобы, по крайней мере, видеть одновременно оба плана на экране и легко переходить от одного к другому.

Вам нет необходимости делать это посредством Query Store - если выполнить щелчок правой кнопкой на любом плане выполнения в SSMS, где теперь есть опция “Compare ShowPlan”, и, поскольку вы уже имеете план, который хотите сравнить с сохраненным в файле, то можете двигаться дальше. Заметим, что хорошо то, что это является функцией SSMS, поэтому, если вы имеете SSMS 2016 или выше, вы можете пользоваться этим для сравнения планов на более ранних версиях SQL Server.

С помощью Query Store вы можете сравнивать планы непосредственно из хранилища. Если мы вернемся к одному из отчетов выше, планы перечислены в легенде точечного графика. Вы можете выбрать более одного плана, используя Shift+ щелчок. Затем вы можете щелкнуть кнопку в панели инструментов выше точечного графика, которая имеет всплывающую подсказку “Compare the Plans for the selected query in separate window” (Сравнить планы для выбранного запроса в отдельном окне).

Давайте сделаем это для двух планов, сформированных выше для нашего запроса. Результат показывает нам два представления рядом. Может быть полезно взглянуть на них по отдельности для лучшего размещения на странице. В левой части имеем:



Выделенная красным область - это то, где инструмент обнаружил совпадение планов. В остальном он не так уверен. Тем не менее, это хорошее визуальное представление, просто чтобы увидеть, что делают оба плана. Справа на экране вы получаете это представление:



Здесь показано сравнение свойств выбранного оператора на каждом плане - отметим, что это не обязательно должен быть эквивалентный оператор на каждом плане. Вы можете выбрать оператор Nested Loop сверху и оператор Index Scan снизу, и они будут показаны - хотя тут сравнение может иметь мало смысла!

Итак, это полезный инструмент, но не следует ожидать от него магического решения процесса сравнения планов за вас. В общем, слишком много различий между планами, чтобы это было так просто — но это может помочь — немного…

Представления каталога хранилища запросов


Подобно всему в SQL Server, вся информация, к которой вы можете получить доступ посредством GUI в SSMS, доступна непосредственно с использованием системных каталогов и представлений. Поэтому, если вы хотите проверить информацию, которая не предоставляется встроенными отчетами, то можете просто написать свои собственные запросы.

Имеются такие новые представления:

sys.database_query_store_options
sys.query_context_settings
sys.query_store_plan
sys.query_store_query
sys.query_store_query_text
sys.query_store_runtime_stats
sys.query_store_runtime_stats_interval

Вместо того, чтобы погружаться в детали, я просто дам ссылку на MSDN:

https://msdn.microsoft.com/en-gb/library/dn818149.aspx

Заключение


Хранилище запросов - замечательная функция. Не космическая, но очень полезная. В частности, она очень помогает исследованию проблем с производительностью, экономя время на их исправления.

Она также полезна для мониторинга производительности во времени и дает возможность опережать проблемы масштабируемости с конкретными запросами.

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

Ссылки по теме
1. Как отключить Query Store...в случае крайней необходимости
2. Сравнение планов запроса в Management Studio
3. О хранилище запросов, навязывании плана и табличных переменных
4. Автоматическая корректировка планов в SQL Server

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Автор не разрешил комментировать эту запись

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.