我有一个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语句获得该订单的索引?如果没有,有没有其他方法可能加快此查询? 感谢您提供的任何帮助!
答案 0 :(得分:1)
您可以从优化CASE语句本身开始。第二个WHEN
是多余的。只能有两种情况(NULL
和NOT NULL
)。简化:
CASE WHEN items.marker is not null
THEN ((items.rating + items.marker) - educations.cards_done)
ELSE 0 END
就索引而言,我不知道如何使用索引中多个表中的值。您必须在其中一个表中使用materialized view或冗余列,可以通过触发器更新。我只考虑这样的事情,如果ORDER
表现非常重要,而且所涉及的表格大部分是读取的,很少写入。
我假设您已在educations.item_id
和items.id
上拥有索引? (主键是自动索引,外键是不。)
根据active = true
项目的百分比,items
上的部分索引可能有所帮助。活跃项目必须是少数才能实现。
CREATE INDEX foo_idx ON items(id) WHERE active;
如果在查询中使用了索引,则使用EXPLAIN ANALYZE
进行测试。如果选择所涉及的表的大部分,则无论如何顺序扫描都会更快并且未使用索引。