Перейти к основному содержимому

Планирование запросов

примечание

Эта страница переведена при помощи нейросети GigaChat.

Конфигурация метода планировщика

Эти параметры конфигурации предоставляют грубый метод влияния на планы запросов, выбираемые оптимизатором запросов. Если план по умолчанию, выбранный оптимизатором для конкретного запроса, не является оптимальным, временное решение состоит в том, чтобы использовать один из этих параметров конфигурации, чтобы заставить оптимизатор выбрать другой план. Лучшие способы улучшения качества планов, выбираемых оптимизатором, включают настройку постоянных затрат планировщика (подробнее в разделе «Постоянные затраты планировщика»), запуск вручную, увеличение значения параметра конфигурации default_statistics_target и увеличение объема статистики, собираемой для определенных столбцов с использованием.

enable_async_append (boolean)

Включает или отключает использование оптимизатором запросов типов планов асинхронного добавления. По умолчанию используется on.

enable_bitmapscan (boolean)

Включает или отключает использование оптимизатором запросов типов планов сканирования битовых карт. По умолчанию используется on.

enable_gathermerge (boolean)

Включает или отключает использование планировщиком запросов типов планов слияния. По умолчанию используется on.

enable_hashagg (boolean)

Включает или отключает использование планировщиком запросов типов агрегированных планов с хешированием. По умолчанию используется on.

enable_hashjoin (boolean)

Включает или отключает использование планировщиком запросов типов планов соединения с использованием хеширования. По умолчанию используется on.

enable_incremental_sort (boolean)

Включает или отключает использование планировщиком запросов инкрементных шагов сортировки. По умолчанию используется on.

enable_indexscan (boolean)

Включает или отключает использование планировщиком запросов типов планов: сканирование по индексу и сканирование только по индексу. По умолчанию используется значение on. Также смотрите enable_indexonlyscan ниже.

enable_indexonlyscan (boolean)

Включает или отключает использование планировщиком запросов типов планов сканирования только по индексу. По умолчанию используется значение on. Параметр enable_indexscan также должен быть включен, чтобы планировщик запросов учитывал сканирование только по индексу.

enable_material (boolean)

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

enable_memoize (boolean)

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

enable_mergejoin (boolean)

Включает или отключает использование планировщиком запросов типа планов слияния. По умолчанию используется on.

enable_nestloop (boolean)

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

enable_parallel_append (boolean)

Включает или отключает использование планировщиком запросов типов параллельных планов добавления. По умолчанию используется on.

enable_parallel_hash (boolean)

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

enable_partition_pruning (boolean)

Включает или отключает возможность планировщика запросов исключать разделы таблицы с разбиением на разделы из планов запросов. Это также контролирует способность планировщика генерировать планы запросов, которые позволяют исполнителю запроса удалять (игнорировать) разделы во время выполнения запроса. По умолчанию используется on. Смотрите Раздел Обрезка разделов для получения подробной информации.

enable_partitionwise_join (boolean)

Включает или отключает использование планировщиком запросов пошагового соединения (partitionwise join), которое позволяет выполнять соединение между секционированными таблицами путем объединения соответствующих секций. В настоящее время пошаговое соединение применяется только тогда, когда условия соединения включают все ключи секций, которые должны иметь один и тот же тип данных и иметь наборы дочерних секций, соответствующие друг другу по принципу «один к одному». При включении этой настройки количество узлов, использование памяти которыми ограничено параметром work_mem, указанным в итоговом плане, может линейно увеличиваться в зависимости от количества сканируемых секций. Это может привести к значительному увеличению общего потребления памяти во время выполнения запроса. Планирование запросов также становится значительно более затратным с точки зрения памяти и ЦП. Значение по умолчанию — off.

enable_partitionwise_aggregate (boolean)

Включает или отключает использование планировщиком запросов группировки или агрегации по разделам, что позволяет выполнять группировку или агрегацию по секционированным таблицам отдельно для каждого раздела. Если предложение GROUP BY не включает ключи разделов, может выполняться только частичная агрегация для каждого раздела, а окончательная обработка должна выполняться позже. При включении этой настройки количество узлов, использование памяти которыми ограничено параметром work_mem, указанным в окончательном плане, может линейно увеличиваться в зависимости от количества сканируемых разделов. Это может привести к значительному увеличению общего потребления памяти во время выполнения запроса. Планирование запросов также становится значительно более затратным с точки зрения памяти и ЦП. Значение по умолчанию — off.

enable_seqscan (boolean)

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

enable_sort (boolean)

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

enable_tidscan (boolean)

Включает или отключает использование планировщиком запросов типов планов сканирования TID. По умолчанию используется значение on.

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

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

Примечание

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

seq_page_cost (floating point)

Устанавливает оценку планировщика стоимости выборки дисковой страницы, которая является частью серии последовательных выборок. По умолчанию это значение равно 1,0. Это значение можно переопределить для таблиц и индексов в определенном табличном пространстве путем установки параметра табличного пространства с тем же именем (смотрите ALTER TABLESPACE).

random_page_cost (floating point)

Устанавливает оценку планировщика стоимости непоследовательно выбранной дисковой страницы. По умолчанию это значение равно 4.0. Это значение можно переопределить для таблиц и индексов в определенном табличном пространстве путем установки параметра табличного пространства с тем же именем (подробнее в разделе «ALTER TABLESPACE» документа «Справочник по языку SQL»).

Уменьшение этого значения относительно seq_page_cost приведет к тому, что система будет предпочитать сканирование индекса; увеличение его сделает сканирование индекса более дорогим. Можно одновременно увеличивать или уменьшать оба значения, чтобы изменить важность затрат на ввод-вывод диска по сравнению со стоимостью CPU, которые описаны следующими параметрами.

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

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

Совет

Хотя система позволит установить random_page_cost меньше чем seq_page_cost, физически это не имеет смысла. Однако установка их равными имеет смысл, если база данных полностью кешируется в RAM, поскольку в этом случае нет штрафа за касание страниц вне последовательности. Кроме того, в сильно кешированной базе данных необходимо снизить оба значения относительно параметров CPU, так как стоимость выборки страницы, уже находящейся в RAM, значительно ниже, чем обычно.

cpu_tuple_cost (floating point)

Устанавливает оценку планировщика стоимости обработки каждой строки во время запроса. По умолчанию - 0,01.

cpu_index_tuple_cost (floating point)

Устанавливает оценку планировщика стоимости обработки каждого индекса при сканировании индекса. По умолчанию - 0,005.

cpu_operator_cost (floating point)

Устанавливает оценку планировщика стоимости обработки каждого оператора или функции, выполняемой во время запроса. По умолчанию это 0,0025.

parallel_setup_cost (floating point)

Задает оценку планировщика стоимости запуска параллельных рабочих процессов. По умолчанию это 1000.

parallel_tuple_cost (floating point)

Устанавливает оценку планировщика стоимости передачи одной кортежа из параллельного рабочего процесса в другой процесс. По умолчанию это 0,1.

min_parallel_table_scan_size (integer)

Устанавливает минимальное количество табличных данных, которые должны быть отсканированы для того, чтобы был рассмотрен параллельный скан. Для параллельного последовательного сканирования объем сканируемых табличных данных всегда равен размеру таблицы, но при использовании индексов объем сканируемых табличных данных обычно будет меньше. Если эта величина указана без единиц измерения, она принимается за блоки, то есть BLCKSZ байт, обычно 8 Кбайт. По умолчанию используется 8 мегабайт (8MB).

min_parallel_index_scan_size (integer)

Устанавливает минимальное количество индексных данных, которые должны быть отсканированы для того, чтобы параллельное сканирование было рассмотрено. Обратите внимание, что при параллельном сканировании индекса обычно не затрагивается весь индекс; важно количество страниц, к которым, по мнению планировщика, действительно будет обращаться сканирование. Этот параметр также используется для определения того, может ли конкретный индекс участвовать в параллельной очистке. Смотрите VACUUM. Если это значение указано без единиц измерения, оно принимается за блоки, то есть BLCKSZ байт, обычно 8 КБ. По умолчанию установлено 512 килобайт (512kB).

effective_cache_size (integer)

Задает предположение планировщика о эффективном размере дискового кеша, доступного для одного запроса. Это учитывается при оценке стоимости использования индекса; более высокое значение делает использование сканирования индекса более вероятным, а меньшее значение делает последовательное сканирование более вероятным. При установке этого параметра следует учитывать как общие буферы PostgreSQL, так и часть дискового кеша ядра, которая будет использоваться для файлов данных PostgreSQL, хотя некоторые данные могут существовать в обоих местах. Также примите во внимание ожидаемое количество одновременных запросов к разным таблицам, поскольку они будут вынуждены делить доступное пространство. Этот параметр не влияет на размер общей памяти, выделяемой PostgreSQL, и не резервирует кеш диска ядра; он используется только для целей оценки. Система также не предполагает, что данные остаются в кеше диска между запросами. Если это значение указано без единиц измерения, оно принимается за блоки, то есть BLCKSZ байт, обычно 8 КБ. По умолчанию установлено 4 гигабайта (4GB). (Если BLCKSZ не равно 8 КБ, значение по умолчанию масштабируется пропорционально ему.)

jit_above_cost (floating point)

Устанавливает стоимость запроса выше которой активируется компиляция JIT, если она включена (смотрите «Компиляция Just-In-Time (JIT)»). Выполнение JIT требует времени планирования, но может ускорить выполнение запроса. Установка этого значения на -1 отключает компиляцию JIT. По умолчанию используется значение 100000.

jit_inline_above_cost (floating point)

Устанавливает стоимость запроса выше которой компиляция JIT пытается встроить функции и операторы. Встраивание добавляет время планирования, но может улучшить скорость выполнения. Не имеет смысла устанавливать это значение меньше чем jit_above_cost. Установка этого значения на -1 отключает встраивание. По умолчанию используется значение 500000.

jit_optimize_above_cost (floating point)

Устанавливает стоимость запроса выше которой компиляция JIT применяет дорогостоящие оптимизации. Такая оптимизация увеличивает время планирования, но может повысить скорость выполнения. Нет смысла устанавливать это значение менее чем jit_above_cost, и вряд ли будет полезно установить его более чем jit_inline_above_cost. Установка этого значения на -1 отключает дорогостоящие оптимизации. По умолчанию используется значение 500000.

Генетический оптимизатор запросов

Генетический оптимизатор запросов (GEQO) - это алгоритм, который выполняет планирование запросов с использованием эвристического поиска. Это сокращает время планирования сложных запросов, объединяющих множество отношений, за счет создания планов, которые иногда уступают тем, что найдены обычным алгоритмом исчерпывающего поиска. Для получения дополнительной информации смотрите главу «Генетический оптимизатор запросов».

geqo (boolean)

Включает или отключает генетическую оптимизацию запросов. По умолчанию это включено. Обычно лучше не отключать его в производстве; переменная geqo_threshold обеспечивает более детальный контроль над GEQO.

geqo_threshold (integer)

Используйте генетическую оптимизацию запросов для планирования запросов с участием не менее этих элементов FROM. (Обратите внимание, что конструкция FULL OUTER JOIN считается только одним элементом FROM). По умолчанию используется значение 12. Для более простых запросов обычно лучше использовать обычный планировщик с исчерпывающим поиском, но для запросов с большим количеством таблиц исчерпывающий поиск занимает слишком много времени, часто дольше, чем штраф за выполнение субоптимального плана. Таким образом, порог размера запроса является удобным способом управления использованием GEQO.

geqo_effort (integer)

Управляет балансом между временем планирования и качеством плана запроса в GEQO. Эта переменная должна быть целым числом в диапазоне от 1 до 10. Значение по умолчанию равно пяти. Более высокие значения увеличивают время, затрачиваемое на планирование запросов, но также повышают вероятность того, что будет выбран эффективный план запроса.

geqo_effort ничего не делает напрямую; он используется только для вычисления значений по умолчанию для других переменных, влияющих на поведение GEQO (описано ниже). Можно установить другие параметры вручную.

geqo_pool_size (integer)

Управляет размером пула, используемого GEQO, то есть количеством особей в генетической популяции. Оно должно быть не менее двух, а полезные значения обычно находятся в пределах от 100 до 1000. Если оно установлено на ноль (значение по умолчанию), то подходящее значение выбирается на основе geqo_effort и количества таблиц в запросе.

geqo_generations (integer)

Управляет количеством поколений, используемых GEQO, т.е. количеством итераций алгоритма. Оно должно быть не менее одного, а полезные значения находятся в том же диапазоне, что и размер пула. Если она установлена на ноль (значение по умолчанию), то подходящее значение выбирается на основе geqo_pool_size.

geqo_selection_bias (floating point)

Управляет смещением выбора, используемым GEQO. Смещение выбора - это селективное давление внутри популяции. Значения могут быть от 1,50 до 2,00; последнее является значением по умолчанию.

geqo_seed (floating point)

Управляет начальным значением генератора случайных чисел, используемого GEQO для выбора случайных путей через пространство поиска порядка соединений. Значение может варьироваться от нуля (значение по умолчанию) до единицы. Изменение значения изменяет набор исследуемых путей соединения и может привести к обнаружению лучшего или худшего оптимального пути.

Другие параметры планировщика

default_statistics_target (integer)

Устанавливает целевую статистику по умолчанию для столбцов таблицы без целевой статистики, установленной с помощью конкретного столбца через ALTER TABLE SET STATISTICS. Большие значения увеличивают время, необходимое для выполнения ANALYZE, но могут улучшить качество оценок планировщика. По умолчанию используется значение 100. Для получения дополнительной информации об использовании статистики планировщиком запросов PostgreSQL смотрите раздел Статистика, используемая планировщиком.

constraint_exclusion (enum)

Управляет использованием планировщиком запросов ограничений таблиц для оптимизации запросов. Допустимые значения constraint_exclusion включают on (проверять ограничения для всех таблиц), off (никогда не проверять ограничения) и partition (проверять ограничения только для дочерних таблиц наследования и UNION ALL подзапросов). Значение по умолчанию - partition. Он часто используется с традиционными деревьями наследования для улучшения производительности.

Когда этот параметр разрешает это для конкретной таблицы, планировщик сравнивает условия запроса с ограничениями таблицы CHECK и пропускает сканирование таблиц, условия которых противоречат ограничениям. Например:

CREATE TABLE parent(key integer, ...);
CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
...
SELECT * FROM parent WHERE key = 2400;

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

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

Смотрите раздел «Партиционирование и исключение по ограничению» для получения дополнительной информации об использовании исключения ограничений для реализации партиционирования.

cursor_tuple_fraction (floating point)

Устанавливает оценку планировщика доли строк курсора, которые будут извлечены. По умолчанию это значение равно 0,1. Меньшие значения этого параметра склоняют планировщик к использованию планов «быстрого старта» для курсоров, которые быстро извлекут первые несколько строк, возможно, затрачивая много времени на получение всех строк. Более высокие значения придают большее значение общей расчетной продолжительности. При максимальной настройке 1,0 курсоры планируются точно так же, как обычные запросы, принимая во внимание только общее оценочное время и не то, насколько скоро могут быть доставлены первые строки.

from_collapse_limit (integer)

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

Установка этого значения на geqo_threshold или больше может вызвать использование планировщика GEQO, что приведет к неоптимальным планам. Смотрите Раздел Генетический оптимизатор запросов.

jit (boolean)

Определяет, может ли JIT компиляция использоваться PostgreSQL, если она доступна (смотрите главу Компиляция Just-In-Time (JIT)). По умолчанию используется on.

join_collapse_limit (integer)

Планировщик будет переписывать явные конструкции JOIN (за исключением FULL JOIN) в списки элементов FROM всякий раз, когда результатом является список не более чем из этого количества элементов. Меньшие значения уменьшают время планирования, но могут привести к менее качественным планам запросов.

По умолчанию эта переменная установлена так же, как from_collapse_limit, что подходит для большинства случаев использования. Установка его равным 1 предотвращает любое изменение порядка явных JOIN. Таким образом, явный порядок соединения, указанный в запросе, будет фактическим порядком, в котором объединяются отношения. Поскольку планировщик запросов не всегда выбирает оптимальный порядок объединения, продвинутые пользователи могут временно установить эту переменную равной 1 и затем явно указать желаемый порядок объединения. Для получения дополнительной информации смотрите раздел «Управление планировщиком с явными предложениями JOIN».

Установка этого значения на geqo_threshold или больше может вызвать использование планировщика GEQO, что приведет к неоптимальным планам. Смотрите Раздел «Генетический оптимизатор запросов».

plan_cache_mode (enum)

Подготовленные операторы (явно подготовленные или неявные, например, сгенерированные PL / pgSQL) могут быть выполнены с использованием пользовательских или общих планов. Пользовательские планы создаются заново для каждого выполнения с использованием своего конкретного набора значений параметров, тогда как общие планы не зависят от значений параметров и могут использоваться повторно при различных исполнениях. Таким образом, использование общего плана экономит время планирования, но если идеальный план сильно зависит от значений параметра, то общий план может оказаться неэффективным. Выбор между этими опциями обычно делается автоматически, но его можно переопределить с помощью plan_cache_mode. Допустимые значения - это auto (по умолчанию), force_custom_plan и force_generic_plan. Этот параметр учитывается при выполнении кешированного плана, а не при его подготовке. Для получения дополнительной информации смотрите PREPARE.

recursive_worktable_factor (floating point)

Устанавливает оценку планировщика среднего размера рабочей таблицы рекурсивного запроса как кратное значение оценки начального нерекурсивного термина запроса. Это помогает планировщику выбрать наиболее подходящий метод соединения рабочей таблицы с другими таблицами запроса. Значение по умолчанию равно 10.0. Меньшее значение, такое как 1.0, может быть полезным, когда рекурсия имеет низкую «разветвление» от одного шага к другому, как, например, в запросах о кратчайших путях. Запросы графического анализа могут выиграть от значений больше, чем значения по умолчанию.