为多列比较强制执行索引扫描[英] Enforcing index scan for multicolumn comparison

本文是小编为大家收集整理的关于为多列比较强制执行索引扫描的处理方法,想解了为多列比较强制执行索引扫描的问题怎么解决?为多列比较强制执行索引扫描问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我知道索引内部是 B-tree 或类似的树结构.假设索引是为 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 列以上的复杂查询,优化器也总是明白他应该执行范围扫描?为什么?

推荐答案

使用 ROW 值 用于比较:

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

(使用 >= 来匹配您的代码,尽管您的描述建议使用 >.两者都可以.)

(a,b,c) 是 ROW(a,b,c) 的缩写,真的.

是的,Postgres 知道它可以使用匹配的 multicolumn B-tree索引(不像其他一些RDBMS - 或者我听说过).

"匹配" 表示所有索引表达式、它们的序列和相关顺序 (ASC|DESC) 相同 - 或者整个索引行的排序顺序完全颠倒,以便 Postgres 可以以几乎相同的速度向后扫描索引.
对于给定的示例,这些索引匹配:

(a ASC, b ASC, c ASC)
(a DESC, b DESC, c DESC)

但是这些不是:

(a ASC, b DESC, c ASC)
(a ASC, c ASC, b ASC)

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

相关,有更多解释:

本文地址:https://www.itbaoku.cn/post/1764171.html