松散的索引搜索postgres有条件

Yo *_*dke 9 postgresql

对于产品表上的某些过滤子条件,我想找出那些过滤产品的不同类别(数百万种产品).

这样做的明确方法

SELECT DISTINCT category_id FROM "products" WHERE _conditions_
Run Code Online (Sandbox Code Playgroud)

当涉及很多行时,需要很长时间才能完成(GROUP BY相反,它并没有真正改变太多)

根据https://wiki.postgresql.org/wiki/Loose_indexscan,当不同的col上只有相对少量的不同值时(就像这里有~30个类别的情况一样),条件

SELECT DISTINCT category_id FROM "products"
Run Code Online (Sandbox Code Playgroud)

可以重新表述为递归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);
Run Code Online (Sandbox Code Playgroud)

这实际上在我的用例(milisecons而不是秒)中表现得更好.但它没有条件.

如何WHERE _conditions_正确地将' '部分添加到递归CTE?

小智 1

WITH RECURSIVE t AS (
   SELECT MIN(category_id) AS category_id FROM "products" WHERE _conditions_
   UNION ALL
   SELECT (SELECT MIN(category_id) FROM "products" WHERE category_id > t.category_id AND _conditions_ )
   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 AND _conditions_);
Run Code Online (Sandbox Code Playgroud)

像这样。其中有三个条件