Комментарии 13
Мне кажется, что для первой части уж больно банальной получилась статья. Стоит обсудить более сложные вопросы. Хабр, все же, не детсад…
Да, конечно, в продолжении будут более сложные вещи. Просто решил начать с самых основ, как в оригинале. Да не рассчитал с объёмом материала. Потому решил разделить на части.
только размечтался об интересностях и на тебе конец части. это заметка о синтаксисе команды EXPLAIN. даешь полную статью
Продолжение следует. Постараюсь ужать оригинал, чтобы уложиться в разумное количество частей.
Интересная тема. Было бы хорошо в следующих частях освятить оптимизацию запросов более подробно (join или подзапрос, тп), может быть рассказать про какие то типы колонок и как они влияют или не влияют на производительность (н-р CHAR, VARCHAR, TEXT).
Еще есть пожелание добавить пару тройку (десятку) ссылок, которые относятся к теме. Может быть освятить опции оптимизатора в postgresql.conf.
Да, в оригинале есть интересные моменты. Полагаю, во второй части успеем разобрать некоторые тонкости.
Неясно, почему бы не сделать нормальный перевод. Зачем выкидывать кучу деталей из статьи, ориентированной на новичков? Один пример:

Такой запрос будет исполняется реально. Так что если вы выполняете EXPLAIN (ANALYZE) для INSERT или UPDATE, ваши данные изменятся. Будьте внимательны! В таких случаях используйте команду ROLLBACK.

Во-первых, без оборачивания в транзакцию от ROLLBACK не будет никакого толка, а во-вторых, ни слова про команду DELETE. Она не изменит данные что ли? Конечно, вещи очевидные, но не для новичков же. А не новички ничего нового не узнают (и им тем более нужны детали). В оригинале, при этом, все ок.

Или еще: «width — средний размер одной строки». В попугаях? Опять надо лезть в оригинал (там все ок).

Сколько строк будет считывать ANALYZE — зависит от параметра default_statistics_target.

В оригинале — 300*default_statistics_target. Четкая и простая зависимость.

Неясно, зачем портить статьи. Советую всем прочитать оригинал.

Согласен с вами. За деталями однозначно — в оригинал.
Своей целью считаю по возможности более краткое изложение оригинала. Некоторые моменты типа 300*default_statistics_target посчитал излишней информацией. Думаю, что для начала достаточно знать, что есть параметр, при помощи которого моно управлять глубиной анализа. Если кому нужна конкретика — она есть в оригинале.
Использование транзакций не входит в тематику статьи. Полагаю, достаточно дать намёк на ROLLBACK. Возможно, напишу отдельную статью про использование транзакций при отладке.
Команду DELETE мне ни разу не приходилось отлаживать, в отличие от UPDATE.
В любом случае, за указание на неточности — спасибо. Подумаю, как лучше внести исправления.
Это не время, а некое сферическое в вакууме понятие, призванное оценить затратность операции.

Если только он запросы делает не в вакууме. Это понятие граничит со временем. Вот что нужно знать про cost:

  • Costs are estimates of the time a node is expected to take
  • By default costs are in units of “time a sequential 8kb block read takes”
  • Each node has two costs, “startup” cost and “total” cost
  • Costs cumulative – parents assume their children's costs
  • Optimizer selects plans based on overall lowest startup and total cost


width — средний размер одной строки.

В байтах.

Статья слишком простая. Нет не про типа scans (Index Scan, Index Only Scan, Bitmap Index Scan), не про типы Jons и сортировок при чтении EXPLAIN.
Не граничит оно никак со временем. Cost зависит от количества операций и их условной стоимости (planner cost constants). Эти константы, по уму, должны зависеть от особенностей машины, где работает постгрес (например, random_page_cost — разная для разных типов дисков, а effective_cache_size зависит от количества доступной памяти). В результате из всех возможных планов выбирается план с наименьшей стоимостью. А время тут ни при чем.

В принципе, при грамотном выставлении planner cost constants теоретически можно добиться того, что cost будет прямо пропорционален затраченному времени, но сама по себе эта связь не обязательна.
Первый и второй пункт в моем коментарии четко говорят, что такое costs: «оценки времени узла, как ожидается, займет при чтении данных», один юнит в основном: время чтения 8kb данных при использовании seq_page_cost. Понятное дело, что он разный при выборе другого плана выполнения:

seq_page_cost — 1.00 — единица
random_page_cost — 4.00 — cost увеличился, поскольку планер берет в 4 раза больше на операцию, но единица измерения осталась та же
cpu_tuple_cost — 0.01 — в 100 раз быстрее seq_page_cost
cpu_operator_cost — 0.0025 — в 400 раз быстрее seq_page_cost
cpu_index_tuple_cost — 0.005 — в 1000 раз быстрее seq_page_cost

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

единица измерения осталась та же

А если в seq_page_cost прописать 3.14, то какой, по-вашему, будет единица измерения?
Так и останется 1. Увеличится число cost в EXPLAIN, где будет seq_page_cost.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.