Ервін, оскільки це було нашим обговоренням у нитці коментарів від цього раніше, я вирішив заглянути ще трохи далі ...
У мене дуже простий запит із таблиці досить розумного розміру. У мене зазвичай достатньо work_mem
, але в цьому випадку я використовував команди
SET work_mem = 64;
встановити дуже маленький work_mem
і
SET work_mem = default;
щоб встановити work_mem
спину достатньо великою для мого запиту.
ПОЯСНЕННЯ та повторна перевірка стану
Отже, запуск мого запиту з лише EXPLAIN
як
EXPLAIN
SELECT * FROM olap.reading_facts
WHERE meter < 20;
Я отримав результати як для низьких, так і для високих work_mem
:
Низький work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32)
Recheck Cond: (meter < 20)
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0)
Index Cond: (meter < 20)
Високий work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32)
Recheck Cond: (meter < 20)
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0)
Index Cond: (meter < 20)
Короткий огляд короткого EXPLAIN
опису, оскільки, як очікується, план запитів вказує, що умова повторної перевірки можлива, але ми не можемо знати, чи насправді буде обчислено.
ПОЯСНІТЬ АНАЛІЗ & Перевірте стан
Коли ми включаємо ANALYZE
в запит, результати повідомляють нам більше про те, що нам потрібно знати.
Низький work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
Recheck Cond: (meter < 20)
Rows Removed by Index Recheck: 86727
Heap Blocks: exact=598 lossy=836
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
Index Cond: (meter < 20)
Високий work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
Recheck Cond: (meter < 20)
Heap Blocks: exact=1434
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
Index Cond: (meter < 20)
Знову ж таки, як і очікувалося, включення ANALYZE
відкриває нам дуже важливу інформацію. У нижньому work_mem
випадку ми бачимо, що є рядки, видалені повторною перевіркою індексу, і що у нас є lossy
блоки купи.
Висновок? (або його відсутність)
На жаль, схоже, що саме EXPLAIN
по собі недостатньо, щоб знати, чи дійсно буде необхідна повторна перевірка індексу, оскільки частина ідентифікаторів рядків відпадає на користь збереження сторінок під час сканування бітової карти.
Використання EXPLAIN ANALYZE
чудово для діагностики проблем із запитами середньої довжини, але у випадку, якщо запит потребує надзвичайно тривалого часу для завершення, то запущення, EXPLAIN ANALYZE
щоб виявити, що ваш індекс бітової карти перетворюється на втрату через недостатнє work_mem
, все ще є важким обмеженням. Мені б хотілося, щоб EXPLAIN
з табличної статистики було оцінено ймовірність цього явища.