Подтвердить что ты не робот

Понимание postgres объясняет w/bitmap heap/index scans

У меня есть таблица с 4.5 миллионами строк. Первичного ключа нет. Таблица имеет столбец p_id, тип integer. Там индекс, idx_mytable_p_id в этом столбце, используя метод btree. Я:

SELECT * FROM mytable WHERE p_id = 123456;

Я объясню это и посмотрю следующий результат:

Bitmap Heap Scan on mytable  (cost=12.04..1632.35 rows=425 width=321)
  Recheck Cond: (p_id = 543094)
  ->  Bitmap Index Scan on idx_mytable_p_id  (cost=0.00..11.93 rows=425 width=0)
        Index Cond: (p_id = 543094)

Вопросы:

  • Почему этот запрос выполняет сканирование кучи, а затем сканирование растрового индекса?
  • Почему он просматривает 425 строк? Почему ширина операции 321?
  • Какова стоимость 12.04..1632.35 и 0.00..11.93, говорящая мне?

Для записи есть 773 строки с p_id значением 123456. На mytable имеется 38 столбцов.

Спасибо!

4b9b3361

Ответ 1

Почему этот запрос выполняет сканирование кучи, а затем сканирование растрового индекса?

Это не так. Вывод EXPLAIN показывает структуру узлов выполнения, причем те, что находятся на "более высоком" уровне (без отступов), вытягивают строки из узлов ниже них. Поэтому, когда "Сканирование битмап-памяти" node переходит в первую строку, выполняется сканирование растрового индекса, чтобы определить набор строк, которые будут использоваться, и передает информацию о первой строке в сканирование кучи. Сканирование индексов передает индекс, чтобы определить, какие строки нужно читать, и кучное сканирование фактически считывает их. Идея состоит в том, что, читая кучу от начала до конца, а не в порядке индекса, она будет делать меньше случайного доступа - все соответствующие строки с данной страницы будут считаны, когда эта страница будет загружена, и достаточно страниц можно прочитать, чтобы использовать более дешевый последовательный доступ, а не искать назад и вперед по всему диску.

Почему он просматривает 425 строк?

Это не так. Вы запустили EXPLAIN, который просто показывает ваши оценки и выбранный план, он вообще не изучает строки. Это делает значение EXPLAIN довольно ограниченным по сравнению с запуском EXPLAIN ANALYZE, который фактически запускает запрос и показывает вам оценки и фактические цифры.

Почему ширина операции 321?

По-видимому, размер, в байтах, кортежей в mytable.

Какова стоимость 12.04..1632.35 и 0.00..11.93, говорящая мне?

Первое число - это стоимость возврата первой строки из этого node; второе число - это стоимость возврата всех строк для этого node. Помните, что это оценки. Единица представляет собой абстрактную стоимость единицы. Абсолютное число ничего не значит; что имеет значение при планировании, какой план имеет самую низкую стоимость. Если вы используете курсор, то имеет значение первый номер; в противном случае это обычно второе число. (Я думаю, что он интерполирует для предложения LIMIT.)

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

Ответ 2

re 1) планы выполнения должны считываться из внутреннего большинства node в самый внешний node. Поэтому сначала выполняется сканирование индекса (для поиска строк) и доступ к фактической таблице для возврата строк, обнаруженных в индексе

re 2) количество строк, показанных в плане, является просто оценкой, основанной на статистике, и поэтому 425 против 773 звучит достаточно разумно. Если вы хотите видеть цифры реальные, используйте explain analyze

re 3) первым номером в стоимостном значении является стоимость "запуска" для инициализации шага планировщика, вторая стоимость - общая стоимость этого шага.

Все это описано в руководстве: http://www.postgresql.org/docs/current/static/using-explain.html

Вы также можете просмотреть эти ссылки в Wiki PostgreSQL:

PostgreSQL EXPLAIN
Использование объяснения