3

ログ ファイルからの情報を格納する Postgres テーブルの最適化に取り組んでいます。

クエリは次のとおりです。

SELECT c_ip as ip
     , x_ctx as file_name
     , date_time
     , live
     , c_user_agent as user_agent 
FROM events 
WHERE x_event = 'play' 
  AND date = '2012-12-01' 
  AND username = 'testing'

x_event、date、および username には b-tree インデックスがあります。このテーブルには、約 2500 万行あります。現在、クエリには約 20 ~ 25 (修正、40 秒程度) かかり、143,000 行が返されます。

その時間は予想されますか?インデックスのおかげでもっと速いと思っていたでしょう。おそらく、通過しなければならない膨大な量のデータのためでしょうか?

編集:これがEXPLAIN ANALYZEです:

Bitmap Heap Scan on events  (cost=251347.32..373829.74 rows=35190 width=56) (actual time=5768.409..6124.313 rows=143061 loops=1)
  Recheck Cond: ((date = '2012-12-01'::date) AND (username = 'testing'::text) AND (x_event = 'play'::text))
  ->  BitmapAnd  (cost=251347.32..251347.32 rows=35190 width=0) (actual time=5762.083..5762.083 rows=0 loops=1)
        ->  Bitmap Index Scan on index_events_fresh_date  (cost=0.00..10247.04 rows=554137 width=0) (actual time=57.568..57.568 rows=572221 loops=1)
              Index Cond: (date = '2012-12-01'::date)
        ->  Bitmap Index Scan on index_events_fresh_username  (cost=0.00..116960.55 rows=6328206 width=0) (actual time=3184.053..3184.053 rows=6245831 loops=1)
              Index Cond: (username = 'testing'::text)
        ->  Bitmap Index Scan on index_events_fresh_x_event  (cost=0.00..124112.84 rows=6328206 width=0) (actual time=2478.919..2478.919 rows=6245841 loops=1)
              Index Cond: (x_event = 'play'::text)
Total runtime: 6148.313 ms

それについていくつか質問があります:

  1. 日付インデックスに 554137 行あるというのは正しいですか? そこにあるはずの日付は50未満です。
  2. リストされている 3 つのインデックスのうち、どのインデックスを使用しているかを知るにはどうすればよいですか?
  3. リストされた合計実行時間は約 6 秒でしたが、EXPLAIN ANALYZE なしでクエリを実行すると、約 40 秒かかります。
4

2 に答える 2

1

まず、Scott Marloweが言うように、クエリの実行には6秒しかかからず、残りは転送時間です。Explain Analysisを使用しないと、結果がExplain Analysisの出力の10行よりもはるかに大きくなり、転送に時間がかかるため、処理が遅くなるようです。クエリのロギングをオンにしてこのクエリを実行した場合、おそらくログで、explainanalyzeのないクエリがさらに高速に実行されることがわかります(explainanalyzeは物事を遅くします)。ところで、それがあなたが使用しているものであるならば、pgadminはそれ自体非常に遅いです。

日付インデックスの行数はpgが正しいです。個別の値が50しかない場合でも、すべての行がインデックスに含まれます。もちろん、btree部分自体には50の異なる値のみが含まれますが、各リーフ値の下には、その値のすべての行のリストがあります。もちろん、where句に一致する行のみを含むwhere句を持つインデックスの特殊なケースがありますが、その権利を使用しているとは思いませんか?

Explainanalyzeの出力にリストされているすべてのインデックスを使用しています。この場合、各インデックスを、そのインデックススキャンの基準に一致する各行のビットセットを持つビットマップに変換します。これらの3つのビットマップは、結合された基準の結果を含むビットマップに非常にすばやく結合できます。

于 2012-12-22T09:01:20.147 に答える
1

5.7 秒では不十分な場合は、複数列のインデックスを試すことができます。

create index index_name on events(user_name, date, x_event)

カーディナリティが最も高い列だと思うので、最初に user_name を配置しました。

于 2012-12-22T11:03:54.593 に答える