2017-07-07 30 views
1

我想問PostgresSQL優化中的幫助。在PostgreSQL統計中,idx_scan非常低

我有一箇中等大小的表(約2000000條記錄),而且我寫了一個非常簡單的查詢,如:

SELECT COUNT (DISTINCT(user_id)) 
FROM fp left outer join sd ON fp.session_id = sd.session_id 
WHERE fp.license_key = 'license' AND sd.device_hash = 'hash' 

我對「許可密鑰」,「USER_ID」和「device_hash」簡單指標(3個索引) 執行程序不想使用我的license_key索引,因爲表中有超過700.000個匹配,Seq Scan是更好的選擇。

Aggregate (cost=396247.61..396247.62 rows=1 width=17) 

    -> Hash Join (cost=99668.54..396152.13 rows=38195 width=17) 

     Hash Cond: ((fp.session_id)::text = (sd.session_id)::text) 

     -> Seq Scan on fp (cost=0.00..293450.55 rows=706957 width=45) 

       Filter: ((license_key)::text = 'license'::text) 

     -> Hash (cost=98678.10..98678.10 rows=79235 width=28) 

       -> Bitmap Heap Scan on sd (cost=2902.50..98678.10 rows=79235 width=28) 

        Recheck Cond: ((device_hash)::text = 'hash'::text) 

        -> Bitmap Index Scan on "sd.device_hash_btree_idx" (cost=0.00..2882.69 rows=79235 width=0) 

          Index Cond: ((device_hash)::text = 'hash'::text) 

我檢查了我的統計數據:

select * from where indexrelname= 'fp_license_key_btree_idx' 

relid | indexrelname | idx_scan | idx_tup_read | idx_fetch 
---------------------------------------------------------------------------- 
16430 |fp.license_key_btree_idx | 451 | 13641445  | 13641445 

你能不能給我建議?我如何改進我的idx_scan?謝謝

回答

0

你可以嘗試用CTE和新指數:

CREATE INDEX ON fp USING btree(session_id); --maybe cover license_key as well, but doubt it 

WITH s AS (SELECT session_id FROM sd WHERE sd.device_hash = 'hash'), 
    f AS (SELECT user_id, session_id 
      FROM fp 
      WHERE fp.license_key = 'license' 
       AND session_id = ANY((SELECT array_agg(session_id) FROM s)::int[])) 
SELECT COUNT (DISTINCT(user_id)) 
FROM f 
JOIN s ON f.session_id = s.session_id; --your left join is not left join anyway 
+0

謝謝你,它變得快4倍。我能再有一個問題嗎?在cte查詢使用位圖索引掃描前的位圖堆掃描,並且它需要95%的查詢時間,我可以以某種方式避免它嗎? –

+0

你不能有一個沒有其他的,但你可以禁用該算法'set enable_bitmapscan ='off'',看看它會做正常的索引掃描,並執行任何更好的。 –