索引扫描以进行多列比较-索引列的非均匀排序 [英] Index scan for multicolumn comparison - non-uniform index column ordering

查看:102
本文介绍了索引扫描以进行多列比较-索引列的非均匀排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该问题与强制进行索引扫描以进行多列比较

这里的解决方案是完美的,但是似乎只有在所有索引列都具有相同排序的情况下才有效。这个问题是不同的,因为这里的b列是 desc ,并且这个事实不再使用行语法来解决相同的问题。这就是为什么我正在寻找其他解决方案。

The solution there is perfect, but seems to works only if all index columns have same ordering. This question is different because column b is desc here, and this fact stops from using row-syntax to solve the same problem. This is why I'm looking for another solution.

假设索引是为3列(a asc,b DESC,c asc),我希望Postgres:

Suppose index is built for 3 columns (a asc, b DESC, c asc), I want Postgres to:


  1. 在以下位置找到键[a = 10,b = 20,c = 30]那个B树

  2. 扫描下10个条目并返回它们。

如果索引仅有一个列,解决方案是显而易见的:

If the index has only one column the solution is obvious:

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

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

But if there are more columns the solution becomes much more complex. For 3 columns:

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

如何告诉Postgres我想要此操作?

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

推荐答案

PostgreSQL非常彻底地实现了元组(不同于Oracle,DB2,SQL Server中的一半实现,等等。)。您可以使用元组不等式来写条件,如:

PostgreSQL implements tuples very thoroughly, (unlike half implementations found in Oracle, DB2, SQL Server, etc.). You can write your condition using "tuples inequality", as in:

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

请注意,由于第二列按降序排列,因此在比较期间必须反转其值。这就是为什么将它表示为 -b 以及 -20 的原因。对于非数字列,例如日期,varchars,LOB等,这可能会很棘手。

Please note that since the second column is in descending order, you must "invert" its value during the comparison. That's why it's expressed as -b and also, -20. This can be tricky for non-numeric columns such as dates, varchars, LOBs, etc.

最后,对于<$ c $,仍可以使用索引c> -b 列值(如果创建临时索引),例如:

Finally, the use of an index is still possible with the -b column value if you create an ad-hoc index, such as:

create index ix1 on table1 (a, (-b), c);

但是,您绝不能强迫PostgreSQL使用索引。 SQL是一种声明性语言,而不是命令性语言。您可以通过保持表状态为最新状态并选择少量行来吸引。如果您的 LIMIT 太大,则PostgreSQL可能会倾向于使用全表扫描。

However, you can never force PostgreSQL to use an index. SQL is a declarative language, not an imperative one. You can entice it to do it by keeping table stats up to date, and also by selecting a small number of rows. If your LIMIT is too big, PostgreSQL may be inclined to use a full table scan instead.

这篇关于索引扫描以进行多列比较-索引列的非均匀排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆