February 8, 2009

Почему делается перепроверка условий (Recheck Cond)?

Перевод Explain: Why do I have to recheck my condition? с Command Prompt Inc., Joshua Drake's blog

Если у вас возник вопрос по PostgreSQL, первым местом, где надо искать ответ должна быть документация по PostgreSQL. Недавно я пересматривал документацию по EXPLAIN, освежая в памяти нюансы по тюнингу запросов и наткнулся на такую вот штуку:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100;

QUERY PLAN
------------------------------------------------------------------------------
Bitmap Heap Scan on tenk1 (cost=2.37..232.35 rows=106 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 < 100)
Что сказано в документации по этому поводу:
В данном случае планировщик решил использовать план в два действия: в нижнем узле 
плана посещается индекс с целью поиска местонахождения строк удовлетворяющих
индексному условию, а в верхнем строки извлекаются уже напрямую из таблицы.
Выборочное чтение строк намного более дорогостоящая операция чем их последовательное
чтение, но т.к. не все страницы таблицы требуется посещать оно оказалось выгоднее.
(Причиной является то, что в верхнем узле плана производится сортировка
местонахождений строк в их физическом порядке, что уменьшает цену выборочного чтения.
"bitmap" упомянутый в именах узлов это механизм, который отвечает за
сортировку.)
В кратце, мы проходим по индексу и выясняем какие записи соответствуют индексному условию (unique1 < 100). Единственное что я не понял и не увидел в документации, это то, почему надо делать перепроверку в верхнем узле (Recheck Cond: (unique1 < 100)), если индекс уже сказал мне, какие записи соответствуют условию.

После небольшого расследования и помощи Neil Conway я нашел причину. Bitmap сканирование является не чётким (loosy) и с ростом количества записей, полученных этим сканированием, PostgreSQL перешел из режима "сопоставления записей" в режим "сопоставления страниц". А так как страницы могут содержать несколько записей, необходимо делать перепроверку (Bitmap Heap scan).

No comments:

Post a Comment