Postgresql
點陣圖堆掃描作為嵌套循環下的內部節點是如何工作的?
我大體上理解
Bitmap Index Scan
其次是如何Bitmap Heap Scan
工作的。但是,我不確定當 a
Bitmap Heap Scan
被選為 a 的內部節點時它是如何工作的Nested Loop
。Nested Loop (cost=86.73..369.99 rows=1 width=37) (actual time=8.487..1823.876 rows=1800 loops=1) -> Bitmap Heap Scan on workspace_history_sets (cost=11.69..141.51 rows=3 width=32) (actual time=6.046..14.218 rows=636 loops=1) Recheck Cond: (workspace_uid = '+++'::uuid) Filter: (((project_uid)::character varying)::text = '---'::text) Heap Blocks: exact=7 -> Bitmap Index Scan on workspace_history_set_idx_workspace_history_set (cost=0.00..11.69 rows=641 width=0) (actual time=0.198..0.198 rows=636 loops=1) Index Cond: (workspace_uid = '+++'::uuid) -> Bitmap Heap Scan on sheets (cost=75.03..76.15 rows=1 width=90) (actual time=2.818..2.836 rows=3 loops=636) Recheck Cond: ((history_set_uid = workspace_history_sets.history_set_uid) AND (project_uid = '---')) Heap Blocks: exact=1800 -> BitmapAnd (cost=75.03..75.03 rows=1 width=0) (actual time=2.752..2.752 rows=0 loops=636) -> Bitmap Index Scan on sheets_idx_history_set_uid (cost=0.00..8.00 rows=551 width=0) (actual time=0.041..0.041 rows=3 loops=636) Index Cond: (history_set_uid = workspace_history_sets.history_set_uid) -> Bitmap Index Scan on sheets_idx_project_uid (cost=0.00..66.39 rows=1573 width=0) (actual time=2.645..2.645 rows=4612 loops=636) Index Cond: (project_uid = '---')
從
EXPLAIN
上面,我們可以看到Bitmap Heap Scan
執行了 636 次(loops=636)
。
- 我是否正確地說每次執行時
Bitmap Heap Scan
它的子節點僅從外部節點檢索到 1 個鍵(索引)?- 如果上述情況屬實,那麼
Bitmap Heap Scan
每個循環的統計數據及其子項不是不同的嗎?那麼這些節點中顯示的數字(actual time=2.818..2.836 rows=3 loops=636)
是什麼意思?它們是所有循環的平均值嗎?
是的,對 sheet_idx_history_set_uid 的點陣圖索引掃描對每 636 個找到的 workspace_history_sets.history_set_uid 值進行一次。報告的實際時間和行數是平均值。
sheet_idx_project_uid 上的點陣圖索引掃描只是重複了 636 次,因為它沒有從外部引用任何值。它可以只執行一次掃描並每次重用點陣圖,但沒有人實施過這種優化。不幸的是,這是您的查詢花費的主要時間。
如果計劃者有更準確的統計數據,它可能只是掃描 sheet_idx_history_set_uid 作為正常索引掃描,然後
project_uid = '---'
作為過濾器進行測試。將 BitmapAnd 用於 551 行似乎比將其用於 3 行更合理。你所有的其他統計數據似乎也很不穩定,你應該對這兩個表進行 VACUUM ANALYZE 以查看這是否會改變事情。多列索引
(history_set_uid, project_uid)
應該提供更好的計劃,這也將更能抵抗不良統計數據的影響。