Хранилище запросов на гибком сервере База данных Azure для PostgreSQL

Хранилище запросов — это функция в База данных Azure для PostgreSQL гибком сервере, который позволяет отслеживать производительность запросов с течением времени. Хранилище запросов упрощает устранение неполадок с производительностью, помогая быстро находить самые длительные и наиболее ресурсоемкие запросы. Хранилище запросов автоматически записывает журнал запросов и статистику среды выполнения и сохраняет их для проверки. Он срезает данные по времени, чтобы увидеть временные шаблоны использования. Данные для всех пользователей, баз данных и запросов хранятся в базе данных с именем azure_sys на гибком сервере База данных Azure для PostgreSQL.

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

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

Это важно

Не включайте Хранилище запросов для ценовой категории Burstable, так как это вызывает проблемы с производительностью.

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

  1. Войдите на портал Azure и выберите База данных Azure для PostgreSQL гибкий сервер.
  2. Выберите Параметры в разделе Настройки меню.
  3. Найдите параметр pg_qs.query_capture_mode.
  4. Задайте значение top или allв зависимости от того, нужно ли отслеживать запросы верхнего уровня или вложенные запросы (те, которые выполняются внутри функции или процедуры), и нажмите кнопку "Сохранить". Подождите до 20 минут, чтобы первый пакет данных сохранился в azure_sys базе данных.

Включить выборку ожиданий в хранилище запросов

  1. Найдите параметр pgms_wait_sampling.query_capture_mode.
  2. Задайте значение all и сохраните его.

Сведения в хранилище запросов

Хранилище запросов состоит из двух хранилищ:

  • Хранилище статистики среды выполнения для сохранения сведений о статистике выполнения запросов.
  • Хранилище статистики ожидания для сохранения сведений статистики ожидания.

Ниже приведены распространенные сценарии использования хранилища запросов:

  • Определение количества выполнения запроса в заданном окне времени.
  • Сравнение среднего времени выполнения запроса в течение нескольких периодов времени, чтобы увидеть большие вариации.
  • Определение самых длительных запросов за последние несколько часов.
  • Определение основных N-запросов, ожидающих ресурсов.
  • Понимание природы ожиданий для конкретного запроса.

Чтобы свести к минимуму использование места, статистика выполнения в хранилище статистики среды выполнения агрегируется в фиксированном настраиваемом окне времени. Данные в этих хранилищах можно запрашивать с помощью представлений.

Доступ к сведениям о хранилище запросов

Гибкий сервер База данных Azure для PostgreSQL хранит данные Query Store в базе данных azure_sys. Следующий запрос возвращает сведения о запросах, записанных хранилищем запросов:

SELECT * FROM  query_store.qs_view;

И этот запрос возвращает сведения о статистике ожидания:

SELECT * FROM  query_store.pgms_wait_sampling_view;

Поиск запросов ожидания

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

Ниже приведены некоторые примеры получения дополнительных сведений о рабочей нагрузке с помощью статистики ожидания в хранилище запросов:

Наблюдение Действие
Высокие задержки при ожидании блокировок Проверьте текст затронутых запросов и выявите целевые сущности. Просмотрите хранилище запросов для других запросов, которые выполняются часто и имеют высокую длительность и изменяют одну и ту же сущность. Найдя такие запросы, рекомендуется изменить логику приложения, чтобы улучшить параллелизм, или использовать менее строгий уровень изоляции.
Высокое время ожидания операций ввода-вывода в буфере Найдите в хранилище запросов запросы с большим числом физических операций чтения. Если они совпадают с запросами с высокими задержками ввода-вывода, рассмотрите возможность включения функции автономной настройки, чтобы проверить, не порекомендует ли она создание индексов, которые могут сократить количество физических операций чтения для этих запросов.
Задержки из-за высокой загрузки памяти Найдите в хранилище запросов те запросы, которые используют больше всего памяти. Эти запросы, вероятно, задерживают дальнейший ход затронутых запросов.

Параметры конфигурации

При включении хранилища запросов он сохраняет данные в окнах агрегирования. Длина этих окон определяется параметром pg_qs.interval_length_minutes , который по умолчанию составляет 15 минут. Для каждого окна хранилище запросов хранит до 500 отдельных запросов. Атрибутами, которые отличают уникальность каждого запроса, являются user_id (идентификатор пользователя, выполняющего запрос), db_id (идентификатор базы данных, в контексте которой выполняется запрос) и query_id (целочисленное значение, уникально определяющее выполняемый запрос). Если количество отдельных запросов достигает 500 в течение заданного интервала, хранилище запросов освобождает 5% записанных запросов, чтобы сделать место для большего. Запросы, освобожденные в первую очередь, — это те, которые были выполнены наименьшее количество раз.

Чтобы настроить параметры хранилище запросов, используйте следующие параметры:

Parameter Описание По умолчанию Диапазон
pg_qs.interval_length_minutes Интервал фиксации данных в минутах для хранилища запросов. Определяет частоту сохраняемости данных. 15 1 - 30
pg_qs.max_captured_queries Максимальное количество запросов из всех запросов, зарегистрированных за каждый интервал сбора, которое сохраняется в хранилище запросов. 500 100 - 500
pg_qs.max_plan_size Максимальное количество байтов, которое сохраняется в хранилище запросов из текста плана запроса. Более длинные планы усечены. 7500 100 - 10000
pg_qs.max_query_text_length Максимальная длина запроса, которую может сохранить хранилище запросов. Более длинные запросы усекаются. 6000 100 - 10000
pg_qs.parameters_capture_mode Указывает, следует ли и когда записывать позиционные параметры запроса. capture_parameterless_only capture_parameterless_only, capture_first_sample
pg_qs.query_capture_mode Утверждения для отслеживания. none none top all
pg_qs.retention_period_in_days Период хранения в днях для хранилища запросов. Старые данные автоматически удаляются. 7 1 - 30
pg_qs.store_query_plans Следует ли сохранять планы запросов в хранилище запросов. off on, off
pg_qs.track_utility Следует ли Query Store отслеживать команды служебных утилит. on on, off

Замечание

Если изменить значение параметра pg_qs.max_query_text_length, текст всех запросов, сохранённых в хранилище запросов до внесения этого изменения, по-прежнему использует те же query_id и sql_query_text. Это поведение может создать впечатление, что новое значение не вступает в силу, однако в случае запросов, которые хранилище запросов ранее не записывало, вы увидите, что текст запроса использует новую настроенную максимальную длину. Такое поведение предусмотрено и объясняется в разделе Представления и функции. Если выполнить команду query_store.qs_reset, будут удалены все сведения, которые хранилище запросов сохранило к настоящему моменту, включая текст, сохранённый для каждого идентификатора запроса. Если любой из этих запросов выполняется повторно, вновь настроенная максимальная длина применяется к захватываемому тексту.

Следующие параметры применяются специально к статистике ожидания:

Parameter Описание По умолчанию Диапазон
pgms_wait_sampling.history_period Частота ( в миллисекундах), при которой выборка событий ожидания выполняется. 100 1 - 600000
pgms_wait_sampling.query_capture_mode Какие утверждения должно отслеживать расширение pgms_wait_sampling. none none, all

Замечание

pg_qs.query_capture_mode заменяет pgms_wait_sampling.query_capture_mode. Если pg_qs.query_capture_mode является none, параметр pgms_wait_sampling.query_capture_mode не действует.

Используйте портал Azure , чтобы получить или задать другое значение параметра.

Представления и функции

Вы можете запросить информацию, записанную хранилищем запросов, и удалить ее с помощью представлений и функций, доступных в схеме query_storeazure_sys базы данных. Любой пользователь в общедоступной роли PostgreSQL может использовать эти представления для просмотра данных в хранилище запросов. Эти представления доступны только в базе данных azure_sys .

Запросы нормализуются за счёт анализа их структуры и игнорирования компонентов, не имеющих семантического значения, таких как литералы, константы, псевдонимы и различия в регистре.

Если два запроса семантически идентичны, то, даже если они используют разные псевдонимы для одинаковых ссылочных столбцов и таблиц, они идентифицируются с тем же идентификатором запроса. Если два запроса отличаются только в литеральных значениях, используемых в них, они также имеют одинаковый query_ID. Для запросов с одинаковым query_id, их sql_query_text соответствует запросу, который был выполнен первым с начала записи активности хранилища запросов или с момента последнего сброса сохраненных данных в результате выполнения функции query_store.qs_reset.

Как работает нормализация запросов

В следующих примерах показано, как работает нормализация запросов:

Предположим, что вы создаете таблицу с помощью следующей инструкции:

create table tableOne (columnOne int, columnTwo int);

Вы включаете хранилище запросов сбор данных, а один или несколько пользователей выполняют следующие запросы в этом точном порядке:

select * from tableOne;
select columnOne, columnTwo from tableOne;
select columnOne as c1, columnTwo as c2 from tableOne as t1;
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one";

Все предыдущие запросы используют один и тот же идентификатор запроса. хранилище запросов сохраняет текст первого запроса, который выполняется после включения сбора данных. Таким образом, текст — select * from tableOne;.

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

select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
select * from tableOne where columnOne = -3 and columnTwo = -3;
select columnOne, columnTwo from tableOne where columnOne = '5' and columnTwo = '5';
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = 7 and columnTwo = 7;

Однако все запросы в этом последнем наборе используют один и тот же идентификатор запроса. Текст, который идентифицирует их все, является текстом первого запроса в пакете: select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;

Наконец, ID следующих запросов не совпадает с ID запросов из предыдущего пакета. Причина, по которой они не соответствуют, объясняется в следующем списке:

Запрос:

select columnTwo as c2, columnOne as c1 from tableOne as t1 where columnOne = 1 and columnTwo = 1;

Причина несоответствия: список столбцов относится к тем же двум столбцам (columnOne и ColumnTwo), но порядок изменится. Порядок меняется с columnOne, ColumnTwo в предыдущем пакете на ColumnTwo, columnOne в этом запросе.

Запрос:

select * from tableOne where columnTwo = 25 and columnOne = 25;

Причина несоответствия: порядок вычисления выражений в предложении WHERE является обратным. Порядок меняется с columnOne = ? and ColumnTwo = ? в предыдущем пакете на ColumnTwo = ? and columnOne = ? в этом запросе.

Запрос:

select abs(columnOne), columnTwo from tableOne where columnOne = 12 and columnTwo = 21;

Причина несоответствия: первое выражение в списке столбцов больше не columnOne, а функция abs, вычисленная из columnOne (abs(columnOne)), которая не является семантически эквивалентной.

Запрос:

select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = ceiling(16) and columnTwo = 16;

Причина несоответствия: первое выражение в предложении WHERE больше не проверяет равенство columnOne с литералом, а с результатом функции ceiling, применённой к литералу, что не является семантически эквивалентным.

Views

query_store.qs_view

Это представление возвращает все данные, которые хранилище запросов сохраняет в своих вспомогательных таблицах. Данные, которые хранилище запросов по-прежнему записывает в памяти для текущего активного периода времени, не отображаются до тех пор, пока не закончится период времени, а переменные в памяти собираются и сохраняются в таблицах, хранящихся на диске. Это представление возвращает другую строку для каждой отдельной базы данных (db_id), пользователя (user_id) и запроса (query_id).

Имя Тип Ссылки Описание
runtime_stats_entry_id Бигинт Идентификатор из таблицы runtime_stats_entries.
user_id oid pg_authid.oid Идентификатор пользователя, выполнившего инструкцию.
db_id oid pg_database.oid OID базы данных, в которой была выполнена инструкция.
query_id Бигинт Внутренний хэш-код, вычисляемый из дерева синтаксического анализа инструкции.
query_sql_text varchar(10000) Текст репрезентативного заявления. Различные запросы с одной структурой кластеризованы вместе. Этот текст является текстом для первого запроса в кластере. Значение по умолчанию для максимальной длины текста запроса составляет 6 000, и его можно изменить с помощью параметра pg_qs.max_query_text_lengthхранилища запросов. Если текст запроса превышает это максимальное значение, оно усечено до первых pg_qs.max_query_text_length байтов.
plan_id Бигинт Идентификатор плана, соответствующего этому запросу.
start_time отметка времени Запросы агрегируются по временным периодам. Параметр pg_qs.interval_length_minutes определяет интервал времени этих окон (по умолчанию — 15 минут). Этот столбец соответствует времени начала окна, в котором была записана запись.
end_time отметка времени Время окончания, соответствующее временному интервалу для этой записи.
calls Бигинт Количество раз, когда запрос выполняется в этом окне времени. Для параллельных запросов число вызовов на каждое выполнение составляет 1 для серверного процесса, который управляет выполнением запроса, плюс ещё по одной единице для каждого серверного рабочего процесса, запускаемого для совместного выполнения параллельных ветвей дерева выполнения.
total_time двойная точность Общее время выполнения запроса в миллисекундах.
min_time двойная точность Минимальное время выполнения запроса в миллисекундах.
max_time двойная точность Максимальное время выполнения запроса в миллисекундах.
mean_time двойная точность Среднее время выполнения запроса в миллисекундах.
stddev_time двойная точность Стандартное отклонение времени выполнения запроса в миллисекундах.
rows Бигинт Общее количество строк, полученных или затронутых инструкцией. Для параллельных запросов число строк для каждого выполнения соответствует количеству строк, возвращаемых клиенту серверным процессом, который управляет выполнением запроса, плюс сумме всех строк, которые каждый серверный рабочий процесс, запущенный для совместного выполнения параллельных ветвей дерева выполнения, возвращает серверному процессу, который управляет выполнением запроса.
shared_blks_hit Бигинт Общее количество попаданий в общий кэш блоков инструкцией.
shared_blks_read Бигинт Общее количество блоков, совместно используемых и прочитанных инструкцией.
shared_blks_dirtied Бигинт Общее количество разделяемых блоков, изменённых запросом.
shared_blks_written Бигинт Общее количество общих блоков, написанных инструкцией.
local_blks_hit Бигинт Общее количество попаданий в кэш локальных блоков запросом.
local_blks_read Бигинт Общее количество локальных блоков, считываемых инструкцией.
local_blks_dirtied Бигинт Общее количество локальных блоков, изменённых запросом.
local_blks_written Бигинт Общее количество локальных блоков, написанных инструкцией.
temp_blks_read Бигинт Общее количество блоков temp, считываемых инструкцией.
temp_blks_written Бигинт Общее количество блоков temp, написанных инструкцией.
blk_read_time двойная точность Общее время, затраченное заявлением на чтение блоков, в миллисекундах (если включен track_io_timing, иначе ноль).
blk_write_time двойная точность Общее время, которое заявление потратило на запись блоков, в миллисекундах (если track_io_timing включен, в противном случае ноль).
is_system_query булевый Определяет, выполняла ли роль с user_id = 10 (azuresu) запрос. Этот пользователь имеет права суперпользователя и используется для выполнения операций контрольной плоскости. Так как эта служба является управляемой службой PaaS, только корпорация Майкрософт является частью этой роли суперпользователя.
query_type текст Тип операции, представленной запросом. Возможные значения: unknown, select, update, insert, delete, merge, utility, nothing, . undefined
search_path текст Значение search_path задано во время записи запроса.
query_parameters текст Текстовое представление объекта JSON со значениями, передаваемыми в позиционные параметры параметризованного запроса. Этот столбец заполняет значение только в двух случаях: 1) для непараметризованных запросов. 2) Для параметризованных запросов, если pg_qs.parameters_capture_mode задано capture_first_sample, и хранилище запросов может получить значения параметров запроса во время выполнения.
parameters_capture_status текст Тип операции, представленной запросом. Возможные значения: succeeded (либо запрос не был параметризован, либо был параметризован, и значения были успешно получены), disabled (запрос был параметризован, но параметры не были получены, поскольку для pg_qs.parameters_capture_mode было задано значение capture_parameterless_only), too_long_to_capture (запрос был параметризован, но параметры не были получены, поскольку длина результирующего JSON, который отображался бы в столбце query_parameters этого представления, была сочтена слишком большой для сохранения в хранилище запросов), too_many_to_capture (запрос был параметризован, но параметры не были получены, поскольку общее количество параметров было сочтено чрезмерным для сохранения в хранилище запросов), serialization_failed (запрос был параметризован, но по крайней мере одно из значений, переданных в качестве параметра, не удалось сериализовать в текст).

query_store.query_texts_view

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

Имя Тип Описание
query_text_id Бигинт Идентификатор таблицы query_texts
query_sql_text varchar(10000) Текст репрезентативного заявления. Различные запросы с одной структурой кластеризованы вместе. Этот текст является текстом для первого запроса в кластере.
query_type smallint Тип операции, представленной запросом. В версиях PostgreSQL <= 14 возможны следующие значения: 0 (неизвестно), 1 (выборка), 2 (обновление), 3 (вставка), 4 (удаление), 5 (служебная команда), 6 (ничего). В версиях PostgreSQL >= 15 возможны следующие значения: 0 (неизвестно), 1 (выборка), 2 (обновление), 3 (вставка), 4 (удаление), 5 (слияние), 6 (служебная операция), 7 (ничего).

query_store.pgms_wait_выборка_view

Это представление возвращает данные о событиях ожидания в хранилище запросов. Это представление возвращает другую строку для каждой отдельной базы данных (db_id), пользователя (user_id), запроса (query_id) и события (события).

Имя Тип Ссылки Описание
start_time отметка времени Запросы агрегируются по временным периодам. Параметр pg_qs.interval_length_minutes определяет интервал времени этих окон (по умолчанию — 15 минут). Этот столбец соответствует времени начала окна, в котором была записана запись.
end_time отметка времени Время окончания, соответствующее временному интервалу для этой записи.
user_id oid pg_authid.oid Идентификатор объекта пользователя, выполнившего инструкцию.
db_id oid pg_database.oid Идентификатор объекта базы данных, в которой была выполнена инструкция.
query_id Бигинт Внутренний хэш-код, вычисляемый из дерева синтаксического анализа инструкции.
event_type текст Тип события, которого ожидает сервер.
event текст Имя события ожидания, если серверная часть в настоящее время ожидает.
calls целое число Количество раз, когда было записано одно и то же событие.

Замечание

Для списка возможных значений в столбцах event_type и event представления query_store.pgms_wait_sampling_view, обратитесь к официальной документации pg_stat_activity и найдите информацию, связанную со столбцами с такими же названиями.

хранилище_запросов.просмотр_планов_запросов

Это представление возвращает план запроса, который использовался для выполнения запроса. Для каждой отдельной базы данных и идентификатора запроса существует одна строка. Хранилище запросов записывает только планы запросов для неутилитарных запросов.

Имя Тип Ссылки Описание
plan_id Бигинт Хэш-значение из нормализованного плана запроса, созданного с помощью команды EXPLAIN. Он находится в нормализованной форме, так как он исключает предполагаемые затраты на узлы плана и использование буферов.
db_id oid pg_database.oid OID базы данных, в которой была выполнена инструкция.
query_id Бигинт Внутренний хэш-код, вычисляемый из дерева синтаксического анализа инструкции.
plan_text varchar(10000) План выполнения инструкции с заданными затратами=false, buffers=false и format=text. Идентичные выходные данные, аналогичные выходным данным, созданным с помощью EXPLAIN.

Functions

query_store.qs_reset

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

query_store.staging_data_reset

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

Режим только для чтения

Если гибкий сервер Базы данных Azure для PostgreSQL находится в режиме только для чтения, например, если default_transaction_read_only параметр установлен onили автоматически включен режим только для чтения из-за достижения емкости хранилища, хранилище запросов не записывает данные.

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