2016-05-08 8 views
2

キャッシング私はPostgresは、キャッシュからデータを立ち退かせるためにLRU /クロックスイープアルゴリズムを使用していることを知っているが、それはどのようになるのshared_buffersに理解することに苦労して。理解Postgresは

私の意図が速く、この素朴なクエリをしないように、インデックスは常に私はキャッシュは、インデックスが存在しない場合にどのように機能するかを理解したい最高のoption.Butであることに注意してください。

はつまり、私たちは、すべてのデータをディスクからフェッチされたことがわかります(私は意図的にインデックスを作成/含まれていない)の例から

performance_test=# explain (analyze,buffers) select count(*) from users; 
                 QUERY PLAN              
----------------------------------------------------------------------------------------------------------------------- 
Aggregate (cost=48214.95..48214.96 rows=1 width=0) (actual time=3874.445..3874.445 rows=1 loops=1) 
    Buffers: shared read=35715 
    -> Seq Scan on users (cost=0.00..45714.96 rows=999996 width=0) (actual time=6.024..3526.606 rows=1000000 loops=1) 
     Buffers: shared read=35715 
Planning time: 0.114 ms 
Execution time: 3874.509 ms 

を以下のクエリ実行プランを取ることができます35715 =読み共有しました。

同じクエリを再度実行した場合。

performance_test=# explain (analyze,buffers) select count(*) from users; 
                 QUERY PLAN              
---------------------------------------------------------------------------------------------------------------------- 
Aggregate (cost=48214.95..48214.96 rows=1 width=0) (actual time=426.385..426.385 rows=1 loops=1) 
    Buffers: shared hit=32 read=35683 
    -> Seq Scan on users (cost=0.00..45714.96 rows=999996 width=0) (actual time=0.036..285.363 rows=1000000 loops=1) 
     Buffers: shared hit=32 read=35683 
Planning time: 0.048 ms 
Execution time: 426.431 ms 

のみ32ページ/ブロックはこれを繰り返すmemory.Whenに入って来た、共有のヒットは32

performance_test=# explain (analyze,buffers) select count(*) from users; 
                 QUERY PLAN              
---------------------------------------------------------------------------------------------------------------------- 
Aggregate (cost=48214.95..48214.96 rows=1 width=0) (actual time=416.829..416.829 rows=1 loops=1) 
    Buffers: shared hit=64 read=35651 
    -> Seq Scan on users (cost=0.00..45714.96 rows=999996 width=0) (actual time=0.034..273.417 rows=1000000 loops=1) 
     Buffers: shared hit=64 read=35651 
Planning time: 0.050 ms 
Execution time: 416.874 ms 

私のshared_buffers = 1ギガバイトで増加し続けると、テーブルのサイズは279メガバイトです。したがって、テーブル全体をメモリにキャッシュすることはできますが、そうではなく、キャッシュは少し違って動作します。誰かがディスクからshared_buffersへデータをどのように計画して移動するか説明できますか?

ページが各クエリでのshared_buffersに移動することができますどのくらいを制御するメカニズムが、あります。

答えて

5

シーケンシャルスキャンによって吹き飛ばされることから、全体のバッファ・キャッシュを防ぐ仕組みがあります。 src/backend/storage/buffer/READMEで説明されています

なVACUUMや大規模な順次スキャンとして、一度だけ多数のページにアクセスする必要があるクエリを実行する場合、異なる戦略が使用されています。そのようなスキャンによってのみタッチされたページはすぐに再び必要になることはほとんどありませんので、通常のクロックスイープアルゴリズムを実行し、バッファキャッシュ全体を吹き飛ばすのではなく、通常のクロックスイープアルゴリズムを使用して、これらのバッファはスキャン全体で再利用されます。これはまた、そのようなステートメントによって引き起こされる書き込みトラフィックの多くは、バックエンド自身によって行われ、他のプロセスにプッシュオフされないことを意味します。

順次スキャンでは、256KBのリングが使用されます。 ...

32×8kB = 256kBだから、見ている通りです。

+0

感謝します。ありがとう。これは私が探していたものでした。 –

関連する問題