按语句索引动态订单

时间:2011-11-23 18:05:35

标签: postgresql activerecord rails-postgresql

我有一个SQL查询我在PostgreSQL中运行,看起来如下:(如果没有尽可能优化,ActiveRecord会产生道歉)

SELECT DISTINCT items.id,
   CASE WHEN items.marker is not null
          THEN (items.rating - (educations.cards_done - items.marker))
        WHEN items.marker is null
          THEN 0 
   END AS order
FROM items
INNER JOIN educations ON educations.item_id = items.id 
WHERE items.active = true
ORDER BY 
   CASE WHEN items.marker is not null
          THEN (items.rating - (educations.cards_done - items.marker))
        WHEN items.marker is null
          THEN 0 
   END
LIMIT 10

是否可以通过PostgreSQL中的case语句获得该订单的索引?如果没有,有没有其他方法可能加快此查询? 感谢您提供的任何帮助!

1 个答案:

答案 0 :(得分:1)

您可以从优化CASE语句本身开始。第二个WHEN是多余的。只能有两种情况(NULLNOT NULL)。简化:

CASE WHEN items.marker is not null 
     THEN ((items.rating + items.marker) - educations.cards_done)
ELSE 0 END

索引而言,我不知道如何使用索引中多个表中的值。您必须在其中一个表中使用materialized view或冗余列,可以通过触发器更新。我只考虑这样的事情,如果ORDER表现非常重要,而且所涉及的表格大部分是读取的,很少写入。

我假设您已在educations.item_iditems.id上拥有索引? (主键是自动索引,外键是。)

根据active = true项目的百分比,items上的部分索引可能有所帮助。活跃项目必须是少数才能实现。

CREATE INDEX foo_idx ON items(id) WHERE active;

如果在查询中使用了索引,则使用EXPLAIN ANALYZE进行测试。如果选择所涉及的表的大部分,则无论如何顺序扫描都会更快并且未使用索引。