F.47. pg_qualstats — статистика по предикатам, найденным в WHERE выражениях и JOIN условиях#

F.47. pg_qualstats — статистика по предикатам, найденным в WHERE выражениях и JOIN условиях

F.47. pg_qualstats — статистика по предикатам, найденным в WHERE выражениях и JOIN условиях #

Версия: 2.1.1

F.47.1. Обзор #

pg_qualstats — это расширение Tantor SE, ведущее статистику по предикатам, найденным в операторах WHERE и предложениях JOIN.

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

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

Расширение работает, ища известные шаблоны в запросах. В настоящее время это включает:

  • Бинарный OpExpr, где хотя бы одна сторона является столбцом из таблицы. Когда это возможно, предикат будет переставлен так, чтобы выражения вида CONST OP VAR преобразовывались в VAR COMMUTED_OP CONST. Элементы выражений AND и OR считаются отдельными записями. Пример: WHERE column1 = 2, WHERE column1 = column2, WHERE 3 = column3

  • ScalarArrayOpExpr, где левая сторона — это VAR, а правая сторона — массив-константа. Такие выражения будут учитываться один раз для каждого элемента массива. Например: WHERE column1 IN (2, 3) будет засчитано как 2 вхождения для пары операторов (column1, "=").

  • BooleanTest, где выражение — это простая ссылка на булевый столбец. Пример: WHERE column1 IS TRUE. Обратите внимание, что такие конструкции, как WHERE column1, WHERE NOT column1 пока не обрабатываются pg_qualstats.

Это расширение также сохраняет текст первого запроса, как есть, для каждого уникального queryid, выполненного с ограничением в pg_qualstats.max записей.

Пожалуйста, обратите внимание, что собранные данные не сохраняются при перезапуске сервера Tantor SE.

F.47.2. Установка #

Добавьте pg_qualstats в общие библиотеки предварительной загрузки:

shared_preload_libraries = 'pg_qualstats'

F.47.3. Конфигурация #

Следующие параметры GUC можно настроить в postgresql.conf:

  • pg_qualstats.enabled (boolean, по умолчанию true): определяет, должен ли быть включён pg_qualstats

  • pg_qualstats.track_constants (boolean, по умолчанию true): указывает, должен ли pg_qualstats отслеживать каждое константное значение отдельно. Отключение этого параметра GUC значительно уменьшит количество записей, необходимых для отслеживания предикатов.

  • pg_qualstats.max: максимальное количество отслеживаемых предикатов и текстов запросов (по умолчанию 1000)

  • pg_qualstats.resolve_oids (boolean, по умолчанию false): определяет, должен ли pg_qualstats разрешать oids во время выполнения запроса или просто сохранять oids. Включение этого параметра значительно упрощает анализ данных, так как подключение к базе данных, где был выполнен запрос, не потребуется, но это будет занимать гораздо больше места (624 байта на запись вместо 176). Кроме того, это потребует некоторых обращений к каталогу, которые не являются бесплатными.

  • pg_qualstats.track_pg_catalog (boolean, по умолчанию false): указывает, должен ли pg_qualstats вычислять предикаты для объектов в схеме pg_catalog.

  • pg_qualstats.sample_rate (double, по умолчанию -1): доля запросов, которые должны быть отобраны для выборки. Например, 0.1 означает, что только один из десяти запросов будет отобран. Значение по умолчанию (-1) означает автоматический режим и приводит к значению 1 / max_connections, так что статистически проблемы с параллелизмом будут редки.

F.47.4. Обновление расширения #

Обратите внимание, что, как и все расширения, указанные в shared_preload_libraries, большинство изменений применяются только после перезапуска Tantor SE с новой версией разделяемой библиотеки. Сами объекты расширения предоставляют только SQL-обёртки для доступа к внутренним структурам данных.

С версии 2.0.4 предоставляется скрипт обновления, позволяющий обновить только из предыдущей версии. Если нужно обновить расширение через несколько версий или из версии старше 2.0.3, вам потребуется удалить и создать расширение заново, чтобы получить последнюю версию.

F.47.5. Использование #

  • Создайте расширение в любой базе данных:

    CREATE EXTENSION pg_qualstats;
    

F.47.5.1. Функции #

Расширение определяет следующие функции:

  • pg_qualstats: возвращает количество для каждого квалификатора, определяемого хэшем выражения. Этот хэш идентифицирует каждое выражение.

    • userid: oid пользователя, который выполнил запрос.

    • dbid: oid базы данных, в которой был выполнен запрос.

    • lrelid, lattnum: oid отношения и номер атрибута VAR с левой стороны, если имеется.

    • opno: oid оператора, используемого в выражении

    • rrelid, rattnum: oid отношения и номер атрибута VAR с правой стороны, если имеется.

    • qualid: нормализованный идентификатор родительского выражения AND, если оно есть. Этот идентификатор вычисляется без учета констант. Это полезно для идентификации предикатов, которые используются вместе.

    • uniquequalid: уникальный идентификатор родительского выражения AND, если оно есть. Этот идентификатор вычисляется с учетом констант.

    • qualnodeid: нормализованный идентификатор этого простого предиката. Этот идентификатор вычисляется без учета констант.

    • uniquequalnodeid: уникальный идентификатор этого простого предиката. Этот идентификатор вычисляется с учетом констант.

    • occurences: количество раз, когда этот предикат был вызван, то есть количество связанных выполнений запроса.

    • execution_count: количество раз, когда этот предикат был выполнен, то есть количество обработанных им строк.

    • nbfiltered: количество кортежей, отброшенных этим предикатом.

    • constant_position: расположение константы в исходной строке запроса, как сообщает парсер.

    • queryid: если установлен pg_stats_statements, идентификатор queryid, определяющий этот запрос, в противном случае NULL.

    • constvalue: строковое представление константы с правой стороны, если есть, обрезанное до 80 байт. Требуется быть superuser или членом pg_read_all_stats, иначе будет показано insufficient privilege.

    • eval_type: тип оценки. f — предикат, вычисляемый после сканирования, или i — индексный предикат.

    Пример:

    ro=# select * from pg_qualstats;
     userid │ dbid  │ lrelid │ lattnum │ opno │ rrelid │ rattnum │ qualid │ uniquequalid │ qualnodeid │ uniquequalnodeid │ occurences │ execution_count │ nbfiltered │ constant_position │ queryid │   constvalue   │ eval_type
    --------+-------+--------+---------+------+--------+---------+--------+--------------+------------+------------------+------------+-----------------+------------+-------------------+---------+----------------+-----------
         10 │ 16384 │  16385 │       2 │   98 │ <NULL> │  <NULL> │ <NULL> │       <NULL> │  115075651 │       1858640877 │          1 │          100000 │      99999 │                29 │  <NULL> │ 'line 1'::text │ f
         10 │ 16384 │  16391 │       2 │   98 │  16385 │       2 │ <NULL> │       <NULL> │  497379130 │        497379130 │          1 │               0 │          0 │            <NULL> │  <NULL> │                │ f
    
  • pg_qualstats_index_advisor(min_filter, min_selectivity, forbidden_am): Выполняет глобальное предложение по созданию индекса. По умолчанию будут рассматриваться только предикаты, фильтрующие не менее 1000 строк и в среднем 30% строк, но эти значения можно передать в качестве параметров. Вы также можете указать массив методов доступа к индексам, если хотите избежать некоторых из них.

    Пример:

    SELECT v
      FROM json_array_elements(
        pg_qualstats_index_advisor(min_filter => 50)->'indexes') v
      ORDER BY v::text COLLATE "C";
                                   v
    ---------------------------------------------------------------
     "CREATE INDEX ON public.adv USING btree (id1)"
     "CREATE INDEX ON public.adv USING btree (val, id1, id2, id3)"
     "CREATE INDEX ON public.pgqs USING btree (id)"
    (3 rows)
    
    SELECT v
      FROM json_array_elements(
        pg_qualstats_index_advisor(min_filter => 50)->'unoptimised') v
      ORDER BY v::text COLLATE "C";
            v
    -----------------
     "adv.val ~~* ?"
    (1 row)
    
  • pg_qualstats_deparse_qual: форматирует сохранённое предикатное выражение в виде tablename.columname operatorname ?. Это в основном используется для глобального советника по индексам.

  • pg_qualstats_get_idx_col: для данного предиката получить имя соответствующего столбца и все возможные классы операторов. Это в основном используется для глобального советника по индексам.

  • pg_qualstats_get_qualnode_rel: для данного предиката возвращает базовую таблицу с полным квалифицированным именем. Это в основном используется для глобального советника по индексам

  • pg_qualstats_example_queries: возвращает все сохранённые тексты запросов.

  • pg_qualstats_example_query: возвращает сохранённый текст запроса для данного queryid, если он есть, в противном случае — NULL.

  • pg_qualstats_names: возвращает все сохранённые тексты запросов.

  • pg_qualstats_reset: сбросить внутренние счетчики и забыть обо всех встреченных условиях qual.

F.47.5.2. Представления #

В дополнение к этому, расширение определяет несколько представлений на основе функции pg_qualstats:

  • pg_qualstats: фильтрует вызовы pg_qualstats() по текущей базе данных.

  • pg_qualstats_pretty: выполняет соответствующие соединения для отображения читаемой агрегированной формы для каждого атрибута из представления pg_qualstats

    Пример:

    ro=# select * from pg_qualstats_pretty;
     left_schema |    left_table    | left_column |   operator   | right_schema | right_table | right_column | occurences | execution_count | nbfiltered
    -------------+------------------+-------------+--------------+--------------+-------------+--------------+------------+-----------------+------------
     public      | pgbench_accounts | aid         | pg_catalog.= |              |             |              |          5 |         5000000 |    4999995
     public      | pgbench_tellers  | tid         | pg_catalog.= |              |             |              |         10 |        10000000 |    9999990
     public      | pgbench_branches | bid         | pg_catalog.= |              |             |              |         10 |         2000000 |    1999990
     public      | t1               | id          | pg_catalog.= | public       | t2          | id_t1        |          1 |           10000 |       9999
    
  • pg_qualstats_all: суммирует количество для каждой пары атрибут / оператор, независимо от позиции в качестве операнда (LEFT или RIGHT), группируя вместе атрибуты, используемые в AND-выражениях.

    Пример:

    ro=# select * from pg_qualstats_all;
     dbid  | relid | userid | queryid | attnums | opno | qualid | occurences | execution_count | nbfiltered | qualnodeid
    -------+-------+--------+---------+---------+------+--------+------------+-----------------+------------+------------
     16384 | 16385 |     10 |         | {2}     |   98 |        |          1 |          100000 |      99999 |  115075651
     16384 | 16391 |     10 |         | {2}     |   98 |        |          2 |               0 |          0 |  497379130
    
  • pg_qualstats_by_query: возвращает только предикаты вида VAR ОПЕРАТОР КОНСТАНТА, агрегированные по queryid.