О Чем Молчит Explain И Как Заставить Его Говорить

Классический вопрос, который разработчик задает своему администратору базы данных или владелец бизнеса консультанту PostgreSQL, почти всегда звучит одинаково: «Почему выполнение запросов к базе данных занимает так много времениЭ» Традиционный набор причин:

  • неэффективный алгоритм когда вы решите ПРИСОЕДИНИТЬСЯ к нескольким CTE на протяжении пары десятков тысяч записей
  • нерелевантная статистика если фактическое распределение данных в таблице уже сильно отличается от собранного ANALYZE в прошлый раз
  • «затыкаться» на ресурсы и выделенных вычислительных мощностей ЦП уже не хватает, гигабайты памяти постоянно перекачиваются, либо диск не успевает за всеми «хотелками» базы данных
  • блокировка от конкурирующих процессов
И если блокировки довольно сложно отловить и проанализировать, то для всего остального нам понадобится план запроса , который можно получить с помощью ОБЪЯСНИТЬ оператор ( Лучше, конечно, сразу ОБЪЯСНИТЬ (АНАЛИЗИРОВАТЬ, БУФЕРИРОВАТЬ).

) или модуль auto_explain .

Но, как указано в той же документации,

«Понимание плана — это искусство, и чтобы овладеть им, требуется определенный опыт…»
Но можно обойтись и без этого, если использовать правильный инструмент! Как обычно выглядит план запроса? Что-то вроде того:
  
  
  
  
   

Index Scan using pg_class_relname_nsp_index on pg_class (actual time=0.049.0.050 rows=1 loops=1) Index Cond: (relname = $1) Filter: (oid = $0) Buffers: shared hit=4 InitPlan 1 (returns $0,$1) -> Limit (actual time=0.019.0.020 rows=1 loops=1) Buffers: shared hit=1 -> Seq Scan on pg_class pg_class_1 (actual time=0.015.0.015 rows=1 loops=1) Filter: (relkind = 'r'::"char") Rows Removed by Filter: 5 Buffers: shared hit=1

или вот так:

"Append (cost=868.60.878.95 rows=2 width=233) (actual time=0.024.0.144 rows=2 loops=1)" " Buffers: shared hit=3" " CTE cl" " -> Seq Scan on pg_class (cost=0.00.868.60 rows=9972 width=537) (actual time=0.016.0.042 rows=101 loops=1)" " Buffers: shared hit=3" " -> Limit (cost=0.00.0.10 rows=1 width=233) (actual time=0.023.0.024 rows=1 loops=1)" " Buffers: shared hit=1" " -> CTE Scan on cl (cost=0.00.997.20 rows=9972 width=233) (actual time=0.021.0.021 rows=1 loops=1)" " Buffers: shared hit=1" " -> Limit (cost=10.00.10.10 rows=1 width=233) (actual time=0.117.0.118 rows=1 loops=1)" " Buffers: shared hit=2" " -> CTE Scan on cl cl_1 (cost=0.00.997.20 rows=9972 width=233) (actual time=0.001.0.104 rows=101 loops=1)" " Buffers: shared hit=2" "Planning Time: 0.634 ms" "Execution Time: 0.248 ms"

Но прочитать план в тексте «с листа» очень сложно и непонятно:
  • отображается в узле сумма по ресурсам поддерева то есть чтобы понять, сколько времени ушло на выполнение того или иного узла, или насколько именно это чтение из таблицы вынесло данные с диска, нужно как-то вычесть одно из другого
  • необходимо время узла умножить на петли да, вычитание - это не самая сложная операция, которую нужно делать "в голове" - ведь время выполнения указано среднее для одного выполнения узла, а их могут быть сотни
  • ну и все это вместе мешает нам ответить на главный вопрос - так кто «самое слабое звено» ?
Когда мы попытались объяснить все это нескольким сотням наших разработчиков, то поняли, что со стороны это выглядит примерно так:

О чем молчит EXPLAIN и как заставить его говорить

А это значит, что нам нужно.



Инструмент

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

Ну и поделитесь частью своего опыта с сообществом.

Знакомьтесь и пользуйтесь - объяснение.

tensor.ru

Видимость планов

Легко ли понять план, когда он выглядит вот так?

Seq Scan on pg_class (actual time=0.009.1.304 rows=6609 loops=1) Buffers: shared hit=263 Planning Time: 0.108 ms Execution Time: 1.800 ms

Не хорошо.

А вот так, в сокращенной форме когда ключевые показатели разделены, все гораздо понятнее:

О чем молчит EXPLAIN и как заставить его говорить

Но если план посложнее, он придет на помощь График распределения времени по узлам:

О чем молчит EXPLAIN и как заставить его говорить

Ну а для самых сложных вариантов он спешит на помощь график прогресса :

О чем молчит EXPLAIN и как заставить его говорить

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

О чем молчит EXPLAIN и как заставить его говорить



О чем молчит EXPLAIN и как заставить его говорить



Структурные подсказки

Ну а если вся структура плана и его слабые места уже изложены и видны, то почему бы не выделить их разработчику и не объяснить на «русском языке»?

О чем молчит EXPLAIN и как заставить его говорить

Мы собрали уже пару десятков таких шаблонов рекомендаций.



Построчный профилировщик запросов

Теперь, если наложить исходный запрос на анализируемый план, то можно увидеть, сколько времени было потрачено на каждый отдельный оператор — примерно так:

О чем молчит EXPLAIN и как заставить его говорить

.

или даже вот так:

О чем молчит EXPLAIN и как заставить его говорить



Подстановка параметров в запрос

Если вы «прикрепили» к плану не только запрос, но и его параметры из строки журнала DETAIL, то его можно дополнительно скопировать в один из вариантов:
  • с подстановкой значений в запросе для непосредственного исполнения на вашей базе и дальнейшего профилирования

    SELECT 'const', 'param'::text;

  • с подстановкой значений через PREPARE/EXECUTE для эмуляции работы планировщика, когда параметрическую часть можно игнорировать — например, при работе с секционированными таблицами

    DEALLOCATE ALL; PREPARE q(text) AS SELECT 'const', $1::text; EXECUTE q('param'::text);



Архив планов

Вставляйте, анализируйте, делитесь с коллегами! Планы останутся в архиве, и вы сможете вернуться к ним позже: объяснение.

tensor.ru/архив Но если вы не хотите, чтобы ваш план увидели другие, не забудьте поставить галочку «не публиковать в архиве».

В следующих статьях я расскажу о трудностях и решениях, которые возникают при анализе плана.

Теги: #базы данных #Администрирование баз данных #postgresql #Визуализация данных #dba #explain #explain.tensor.ru

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.