2016-03-22 78 views
0

我對Postgres的表有一個有趣的案例與選擇:PostgreSQL的優化:Sequantial掃描VS索引掃描

advert (~2.5 million records) 
    id serial, 
    user_id integer (foreign key), 
    ... 

這是我的選擇:

select count(*) from advert where user_id in USER_IDS_ARRAY 

如果USER_IDS_ARRAY長度< = 100我有接下來解釋一下分析:

Aggregate (cost=18063.36..18063.37 rows=1 width=0) (actual time=0.362..0.362 rows=1 loops=1) 
    -> Index Only Scan using ix__advert__user_id on advert (cost=0.55..18048.53 rows=5932 width=0) (actual time=0.030..0.351 rows=213 loops=1) 
     Index Cond: (user_id = ANY ('{(...)}')) 
     Heap Fetches: 213 
Planning time: 0.457 ms 
Execution time: 0.392 ms 

但是當USER_IDS_ARRAY長度> 100:

Aggregate (cost=424012.09..424012.10 rows=1 width=0) (actual time=867.438..867.438 rows=1 loops=1) 
    -> Seq Scan on advert (cost=0.00..423997.11 rows=5992 width=0) (actual time=0.375..867.345 rows=213 loops=1) 
     Filter: (user_id = ANY ('{(...)}')) 
     Rows Removed by Filter: 2201318 
Planning time: 0.261 ms 
Execution time: 867.462 ms 

無論USER_IDS_ARRAY中的user_id是什麼,只有它的長度很重要。

有沒有人有想法如何優化這個select超過100個user_ids?

+0

您是否嘗試過從'advert'中選擇沒有連接?使用> 100個用戶ID進行過濾,看看它是否使用索引。 – Sevanteri

+0

@ Sevanteri是的,你是對的,與廣告選擇相同的情況。只用一張表簡化我的問題。 –

+0

對。看起來查詢計劃者只是認爲最好是使用seq掃描。你可以爲表格運行['analyze'](http://www.postgresql.org/docs/current/static/sql-analyze.html),看看它是否有幫助。 – Sevanteri

回答

3

如果SET enable_seqscan = OFF仍然不強制索引掃描,這意味着索引掃描是不可能的。結果發現這個指數是部分的。