由于ORDER BY子句,PGSQL没有执行我的索引吗?

时间:2017-07-26 18:50:22

标签: ruby-on-rails postgresql

我有一个看起来像这样的rails查询:

Person.limit(10).unclaimed_people({})

def unclaimed_people(opts)
  sub_query = where.not(name_id: nil)
  if opts[:q].present?
    query_with_email_or_name(sub_query, opts)
  else
    sub_query.group([:name_id, :effective_name])
             .reorder('MIN(COALESCE(kudo_position,999999999)), lower(effective_name)')
             .select(:name_id)
  end
end

转换为SQL,查询如下所示:

SELECT  "people"."name_id" FROM "people" 
  WHERE ("people"."name_id" IS NOT NULL)
GROUP BY "people"."name_id", "people"."effective_name"
  ORDER BY MIN(COALESCE(kudo_position,999999999)), lower(effective_name) LIMIT 10

现在,当我在SQL查询上运行EXPLAIN时,返回的内容表明我没有运行索引扫描。这是EXPLAIN

     QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=728151.18..728151.21 rows=10 width=53) (actual time=6333.027..6333.028 rows=10 loops=1)
   ->  Sort  (cost=728151.18..729171.83 rows=408258 width=53) (actual time=6333.024..6333.024 rows=10 loops=1)
         Sort Key: (min(COALESCE(kudo_position, 999999999))), (lower(effective_name))
         Sort Method: top-N heapsort  Memory: 25kB
         ->  GroupAggregate  (cost=676646.88..719328.87 rows=408258 width=53) (actual time=4077.902..6169.151 rows=946982 loops=1)
               Group Key: name_id, effective_name
               ->  Sort  (cost=676646.88..686041.57 rows=3757877 width=21) (actual time=4077.846..5106.606 rows=3765261 loops=1)
                     Sort Key: name_id, effective_name
                     Sort Method: external merge  Disk: 107808kB
                     ->  Seq Scan on people  (cost=0.00..112125.78 rows=3757877 width=21) (actual time=0.035..939.682 rows=3765261 loops=1)
                           Filter: (name_id IS NOT NULL)
                           Rows Removed by Filter: 317644
 Planning time: 0.130 ms
 Execution time: 6346.994 ms

注意查询计划的底部。有一个Seq Scan on people。这不是我所期望的,在我的开发和生产数据库中,我在外部name_id字段上放置了一个索引。以下是people表的证据。

"index_people_name_id" btree (name_id) WHERE name_id IS NOT NULL

所以我的问题是为什么它不会运行索引。它可能来自ORDER BY条款。我读到它可能会影响索引的执行。这是我从中读取它的网页。 Why isn't my index being used?

特别是这里是页面的引用。

  

索引通常不用于ORDER BY或执行连接。顺序扫描后跟显式排序通常比大表的索引扫描更快。但是,LIMIT与ORDER BY相结合通常会使用索引,因为只返回表的一小部分。

从查询中可以看出,我使用ORDER BYLIMIT结合使用,所以我希望能够使用索引。这会过时吗? ORDER BY真的会影响查询吗?为了让索引工作,我错过了什么?我并不是特别熟悉PGSQL的内部,所以任何帮助都会受到赞赏。

0 个答案:

没有答案