0

我有一个我在 PostgreSQL 中运行的 SQL 查询,看起来像这样:(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 语句对该顺序进行索引?如果没有,有没有其他方法可以加快这个查询?感谢您的任何帮助,您可以提供!

4

1 回答 1

1

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

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

索引而言,我不知道有一种方法可以在索引中使用多个表中的值。为此,您必须在其中一个表中使用物化视图或冗余列,这可以通过触发器进行更新。我只会考虑这样的事情,如果ORDER性能非常重要并且所涉及的表主要是读取而很少写入。

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

根据具有active = true部分索引的项目的百分比items可能会有所帮助。活动项目必须是少数才能发挥作用。

CREATE INDEX foo_idx ON items(id) WHERE active;

测试EXPLAIN ANALYZE是否在查询中使用索引。如果您选择涉及的表的大部分,顺序扫描无论如何都会更快并且不使用索引。

于 2011-11-23T18:59:53.670 回答