【发布时间】:2015-07-02 16:04:46
【问题描述】:
对于产品表上的某些过滤子条件,我想找出这些过滤产品的不同类别(数百万个产品)。
明确的做法
SELECT DISTINCT category_id FROM "products" WHERE _conditions_
当涉及到很多行时需要很长时间才能完成(改用GROUP BY 并没有太大变化)
根据https://wiki.postgresql.org/wiki/Loose_indexscan,当不同列上只有相对少量的不同值时(就像这里的情况一样,有大约 30 个类别),条件
SELECT DISTINCT category_id FROM "products"
可以重述为递归 CTE
WITH RECURSIVE t AS (
SELECT MIN(category_id) AS category_id FROM "products"
UNION ALL
SELECT (SELECT MIN(category_id) FROM "products" WHERE category_id > t.category_id)
FROM t WHERE t.category_id IS NOT NULL
)
SELECT category_id FROM t WHERE category_id IS NOT NULL
UNION ALL
SELECT NULL WHERE EXISTS(SELECT 1 FROM "products" WHERE category_id IS NULL);
这实际上在我的用例中表现更好(毫秒而不是秒)。 但它是没有条件的。
如何在递归 CTE 中正确添加“WHERE _conditions_”部分?
【问题讨论】:
-
嗯。这是一个聪明的把戏。它还表明优化器缺少一个技巧,尽管可能存在细微的语义差异。
-
我不确定你的意思,但我想在 postgres 中更好地支持松散索引扫描会非常整洁
-
这里的查询计划器中有一个松散索引扫描的功能请求:postgresql.uservoice.com/forums/21853-general/suggestions/… 可以通过投票
-
这意味着没有人热衷于做这项工作或资助其他人去做。这就是独立开源项目的情况。告诉我什至不知道 PostgreSQL 有一个“用户语音”部分,并且之前没有看到任何地方提到过它
-
“开源”有这么多吗?如果您希望 MS SQL 的某个功能,您也无法知道该功能是否会在某个时候实现..
标签: postgresql