2011-11-23 50 views
0

动态顺序我有一个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

您可以从优化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进行测试。如果您选择涉及的表的大部分,顺序扫描将会更快,索引也不会被使用。