【问题标题】:loose index search postgres with conditions有条件的松散索引搜索postgres
【发布时间】: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


【解决方案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_);

像这样。有三个条件

【讨论】:

  • 这适用于我的数据以使用索引,尽管它现在在数百毫秒的范围内(我猜这对于表大小和条件来说是可以的)
猜你喜欢
  • 2012-03-07
  • 2016-06-02
  • 2023-03-05
  • 2020-12-24
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多