私の誤解を次の例で説明します。
の基本を理解していませんでしたBitmap Heap Scan Node
。SELECT customerid, username FROM customers WHERE customerid < 1000 AND username <'user100';
計画がこれであるクエリを検討してください。
Bitmap Heap Scan on customers (cost=25.76..61.62 rows=10 width=13) (actual time=0.077..0.077 rows=2 loops=1)
Recheck Cond: (((username)::text < 'user100'::text) AND (customerid < 1000))
-> BitmapAnd (cost=25.76..25.76 rows=10 width=0) (actual time=0.073..0.073 rows=0 loops=1)
-> Bitmap Index Scan on ix_cust_username (cost=0.00..5.75 rows=200 width=0) (actual time=0.006..0.006 rows=2 loops=1)
Index Cond: ((username)::text < 'user100'::text)
-> Bitmap Index Scan on customers_pkey (cost=0.00..19.75 rows=1000 width=0) (actual time=0.065..0.065 rows=999 loops=1)
Index Cond: (customerid < 1000)
このノードの私の理解:
そこに説明されているように、bitmap heap scan
テーブルブロックを順番に読み取ります。そのため、justを実行するときに発生するランダムテーブルアクセスのオーバーヘッドは発生しませんIndex Scan
。
後にIndex Scan
行われた、PostgreSQLは不必要な避けるために、最適な行をフェッチする方法を知らないheap blocks reads
(またはhits
ホットキャッシュが存在する場合)。だからそれを理解するために、それは私の場合はインデックスの2つのビットマップを生成して実行することによって生成されているBitmap Index Scan
と呼ばれる構造体()をbitmap
生成しますBITWISE AND
。ビットマップが生成されたため、不要なを避けて、テーブルを順番に最適に読み取ることができるようになりましたheap I/O-operations
。
それは多くの質問が来る場所です。
質問:ビットマップだけがあります。PostgreSQLは、ビットマップだけで行の物理的順序をどのように認識していますか?または、ビットマップを生成して、その要素をページへのポインターに簡単にマップできるようにしますか?もしそうなら、それはすべてを説明しますが、それはちょうど私の推測です。
だから、単純bitmap heap scan -> bitmap index scan
にテーブルの適切な部分だけのシーケンシャルスキャンのようなものだと言えますか?
001001010101011010101
。または、実際には問題ではなく、ビットマップのブロックを非常に高速に見つけることができるということだけを知っている必要があります...?