trans_type FROM fb_iss_fin_auth
WHERE (is_processed_by_sms = false) AND (((is_processed_by_abs = true) AND
(abs_out_answer = '0')) OR (trans_type = 702))
c таким EXPLAIN:
Bitmap Heap Scan on fb_iss_fin_auth (cost=172.87..19299.19 rows=85308 width=960) (actual time=1.436..16.926 rows=4640 loops=1)
Recheck Cond: (((NOT is_processed_by_sms) AND is_processed_by_abs AND ((abs_out_answer)::text = '0'::text)) OR ((NOT is_processed_by_sms) AND (trans_type = 702)))
Filter: ((NOT is_processed_by_sms) AND ((is_processed_by_abs AND ((abs_out_answer)::text = '0'::text)) OR (trans_type = 702)))
Heap Blocks: exact=4588
Buffers: shared hit=3264 read=1340
-> BitmapOr (cost=172.87..172.87 rows=5143 width=0) (actual time=0.983..0.983 rows=0 loops=1)
Buffers: shared hit=3 read=13
-> Bitmap Index Scan on ix_fb_iss_fin_auth_complex1 (cost=0.00..125.93 rows=5129 width=0) (actual time=0.967..0.967 rows=4987 loops=1)
Index Cond: ((is_processed_by_sms = false) AND (is_processed_by_abs = true) AND ((abs_out_answer)::text = '0'::text))
Buffers: shared hit=3 read=12
-> Bitmap Index Scan on ix_fb_iss_fin_auth_complex2 (cost=0.00..4.28 rows=14 width=0) (actual time=0.014..0.014 rows=37 loops=1)
Index Cond: ((is_processed_by_sms = false) AND (trans_type = 702))
Buffers: shared read=1
Можете подсказать почему Bitmap Heap Scan оценил rows=85308, хотя он должен показать по оценке BitmapOr - rows=5143? Или как это работает?))
А если отключать enable_* до того, пока не получится seq.scan — какая будет оценка (для проверки достаточно EXPLAIN без ANALYZE)?
Потому что PostgreSQL не может установить, что они эквивалентны (он этим не сильно "заморачивается" в подобных ситуациях). Да, Recheck Cond в данном случае всё равно не выполняется, так что это не так уж страшно.
Отключил bitmapscan и max_parallel_workers и seqscan дал ту же самую цифру - 85308
А в чем проблема в оценке?) если в совершенствование планировщика то ок. А так тол да надо проверить в теории
Т.е. оценка выборки строится по статистикам полей (в предположении их независимого распределения), получается. Так и должно быть, насколько я помню — таким образом она не зависит от выбранного метода доступа (а иначе бы могло бы получаться, что для того же условия при фильтрации, например, по индексам была бы одна оценка, а без них — другая, а это бред).
Я пытаюсь понять как это работает. Я так понимаю, что Bitmap Heap Scan в своей оценке просто посчитал нечто из статистики, а не взял оценку из нижележащего узла дерева выполнения (BitmapOr). Не понимаю почему именно так, а не иначе.
Я же Вам выше написал, почему, нет?
По идее можно прикрутить некоторую расширенную статистику для более точной оценки если очень хочется?))
Так у вас вроде с actual значениями все нормально было?
Да, по идее можно — см. https://www.postgresql.org/docs/current/sql-createstatistics.html ... но насколько это поможет, это другой вопрос (в запросе нетривиальное условие, а с их оценками даже при наличии extended statistics PostgreSQL, кажется, справляется не очень хорошо).
скорее можно просто изменить праметры сбора статисики для таблиц в запросе
А почему он не выполняется? По-моему, написано, что он нужэн, возвращается 4k строчек — вроде для каждой должэн быть выполнен.
Потому что в плане: Heap Blocks: exact=4588 Нет lossy, что значит, что recheck не нужен и не выполняется (а вот сам он есть в плане всегда, потому что только при выполнении становится понятно, хватит ли памяти для bitmap или нет). Это, к сожалению, не очевидно, да... но подобных мест в explain-ах PostgreSQL хватает, в общем. В основном, это потому, что "Extensibility is a harsh mistress." © Tom Lane
Обсуждают сегодня