连接表时未使用索引

时间:2017-06-22 12:19:22

标签: sql postgresql

我们有四个表:

  • 列表
  • influencer_lists(连接表)

这是查询:

SELECT influencer_lists.influencer_id 
FROM influencer_lists
LEFT OUTER JOIN lists ON lists.id = influencer_lists.list_id
WHERE influencer_lists.influencer_id IN (12, 95, 33, 23, 35, 36, 27, 41, 42, 43, 45, 30) 
AND "lists"."user_id" = 1

在做解释时,注意到两件事:

  1. 在寻找influencer_id时,某些时候没有使用索引
  2. 正在使用索引
  3. EXPLAIN输出:

    Nested Loop  (cost=0.28..73.59 rows=9 width=4) (actual time=0.031..0.187 rows=4 loops=1)
    ->  Seq Scan on influencer_lists  (cost=0.00..10.82 rows=9 width=8) (actual time=0.016..0.152 rows=5 loops=1)
    Filter: (influencer_id = ANY ('{12,95,33,23,35,36,27,41,42,43,45,30}'::integer[]))
    Rows Removed by Filter: 308
    ->  Index Scan using lists_pkey on lists  (cost=0.28..6.96 rows=1 width=4) (actual time=0.005..0.005 rows=1 loops=5)
    Index Cond: (id = influencer_lists.list_id)
    Filter: (user_id = 1)
    Rows Removed by Filter: 0
    Planning time: 0.621 ms
    Execution time: 0.235 ms
    

    我们希望改善查询时间。我们怎么做呢?

    感谢。

2 个答案:

答案 0 :(得分:0)

我建议的第一件事是更新所涉及的表的统计数据。如果您有经验表现,这是一个很好的开始。

 ANALYZE [tablename] ;

其次,因为此列上有索引,并不意味着它将始终使用。 “IN”子句中的值范围可能包含太多的id以保证使用索引。您可以尝试个人id = [value]

答案 1 :(得分:0)

如果SELECT返回的表中所有行的返回值大于约5-10%(取决于配置设置以及数据的存储。它不是硬数),顺序扫描比索引快得多扫描。

索引扫描每行需要多次IO操作(查找索引中的行,然后从堆中检索行)。顺序扫描每行只需要一个IO - 甚至更少,因为磁盘上的块(页面)包含多行,因此可以通过单个IO操作获取多个行。