簡體   English   中英

為什么Postgresql不對IN查詢使用索引?

[英]Why doesn't Postgresql use index for IN query?

我有一個表social_accounts ,在facebook_id列上具有部分索引,其中user_id IS NULL

如果我執行簡單查詢WHERE facebook_id = '123' ,則使用索引:

 => EXPLAIN for: SELECT "social_accounts".* FROM "social_accounts"  WHERE (user_id IS NOT NULL) AND "social_accounts"."facebook_id" = '123'
                                                  QUERY PLAN
--------------------------------------------------------------------------------------------------------------
 Index Scan using index_social_accounts_on_facebook_id on social_accounts  (cost=0.00..8.28 rows=1 width=345)
   Index Cond: ((facebook_id)::text = '123'::text)
   Filter: (user_id IS NOT NULL)

但是如果我使用IN進行查詢,則不會使用索引:

 => EXPLAIN for: SELECT "social_accounts".* FROM "social_accounts"  WHERE (user_id IS NOT NULL) AND "social_accounts"."facebook_id" IN ('123', '456')
                                            QUERY PLAN
---------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on social_accounts  (cost=8.53..16.36 rows=2 width=345)
   Recheck Cond: ((facebook_id)::text = ANY ('{123,456}'::text[]))
   Filter: (user_id IS NOT NULL)
   ->  Bitmap Index Scan on index_social_accounts_on_facebook_id  (cost=0.00..8.52 rows=2 width=0)
         Index Cond: ((facebook_id)::text = ANY ('{123,456}'::text[]))
(5 rows)

為什么在第二種情況下不使用索引? 有什么辦法可以加快這個查詢?

(請注意,在此示例中,我已截斷了數組,並測試了更多元素,但結果卻相同,緩慢)

實際上,它正在使用索引。 只是這樣做不同。

索引掃描逐行訪問,以隨機順序從一個磁盤頁面到下一個磁盤頁面來回移動。

位圖索引掃描首先過濾要訪問的磁盤頁面,然后依次逐個訪問后者。 重新檢查條件是因為隨后需要在每個頁面中過濾掉無效的行。

對於極少數的行,索引掃描是最便宜的。 對於更多行,位圖索引掃描變得最便宜。 對於更大數量的行,seq掃描最終將變得最便宜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM