简体   繁体   English

为什么Postgresql不对IN查询使用索引?

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

I have a table social_accounts with a partial index on column facebook_id where user_id IS NULL . 我有一个表social_accounts ,在facebook_id列上具有部分索引,其中user_id IS NULL

If I do a simple query WHERE facebook_id = '123' , the index is used: 如果我执行简单查询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)

but if I do a query using IN it does not use the index: 但是如果我使用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)

why doesn't it use the index in the second case? 为什么在第二种情况下不使用索引? any way to speed up this query? 有什么办法可以加快这个查询?

(note that for this example I have truncated the array, and I've tested with many more elements but with same, slow, results) (请注意,在此示例中,我已截断了数组,并测试了更多元素,但结果却相同,缓慢)

Actually, it is using an index. 实际上,它正在使用索引。 Just doing so differently. 只是这样做不同。

An index scan visit rows one by one, going back and forth from one disk page to the next in random order. 索引扫描逐行访问,以随机顺序从一个磁盘页面到下一个磁盘页面来回移动。

A bitmap index scan starts by filtering disk pages to visit, and then visits the latter one by one sequentially. 位图索引扫描首先过滤要访问的磁盘页面,然后依次逐个访问后者。 The recheck cond is because, in each page, you then need to filter out invalid rows. 重新检查条件是因为随后需要在每个页面中过滤掉无效的行。

For tiny numbers of rows, index scan is cheapest. 对于极少数的行,索引扫描是最便宜的。 For more rows, bitmap index scan becomes cheapest. 对于更多行,位图索引扫描变得最便宜。 For even larger numbers of rows, a seq scan eventually becomes cheapest. 对于更大数量的行,seq扫描最终将变得最便宜。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM