强制执行索引扫描以进行多列比较

问题描述 投票:1回答:1

我知道索引内部是B树或类似的树结构。假设索引是为3列(a,b,c)构建的,我希望Postgres:

  1. 在该B树中找到关键字[a = 10,b = 20,c = 30],
  2. 扫描下10个条目并返回它们。

如果索引只有一列,那么解决方案是显而易见的:

select * from table1
where a >= 10
order by a limit 10

但是如果有更多的列,解决方案变得更加复杂。对于2列:

select * from table1
where a > 10 or (a = 10 and b >= 20)
order by a, b limit 10

3列:

select * from table1
where a > 10 or (a = 10 and (b > 20 or b = 20 and c >= 30))
order by a, b, c limit 10

请注意查询:

select * from table1
where a >= 10 and b >= 20 and c >= 30
order by a, b, c limit 10

是不正确的,因为它会过滤掉例如[a = 11,b = 10,c = 1]。

我怎么能告诉Postgres我想要这个操作?

我是否可以确定即使对于2列以上的复杂查询,优化器也会始终了解他应该执行范围扫描?为什么?

sql postgresql indexing
1个回答
3
投票

使用ROW values进行比较:

SELECT *
FROM   table1
WHERE  (a,b,c) >= (10, 20, 30)
ORDER  BY a,b,c
LIMIT  10;

(使用qazxsw poi来匹配你的代码,通过你的描述建议qazxsw poi。要么有用。)

>=>的缩写,真的。

是的,Postgres明白它可以使用匹配的(a,b,c)(不像其他一些RDBMS - 或者我听说过)。

“匹配”意味着所有索引表达式,它们的顺序和相关顺序(ROW(a,b,c) | multicolumn B-tree index)都是相同的 - 或者整个索引行的排序顺序完全颠倒,以便Postgres可以以几乎相同的速度向后扫描索引。 对于给定的示例,这些索引匹配:

ASC

但这些不是:

DESC

优化一系列时间戳(两列)的查询

相关,有更多解释:

  • (a ASC, b ASC, c ASC) (a DESC, b DESC, c DESC)
  • (a ASC, b DESC, c ASC) (a ASC, c ASC, b ASC)
© www.soinside.com 2019 - 2024. All rights reserved.