EXTRACT(日)的表现与BETWEEN相比如何?

hur*_*lad 1 postgresql indexing datetime

我在一段时间内查询PostgreSQL表中的行. BETWEEN是一个常见的建议:

WHERE ts BETWEEN '2015-09-01' AND '2015-10-01'
Run Code Online (Sandbox Code Playgroud)

我也见过EXTRACT用过:

WHERE EXTRACT(month from ts) = 9
Run Code Online (Sandbox Code Playgroud)

假设ts是一个索引timestamp列,可以EXTRACT匹配的速度BETWEEN?如果是这样,我特别好奇它是如何实现的.

Cra*_*ger 6

B树索引,这是默认的索引类型,可用于操作>,<,>=,<==即排序和平等.

当您使用函数以转换值的方式转换输出,使其无法在索引中逐字查找时,您不能使用索引进行查找.

情况就是如此EXTRACT(day from ts).您无法对转换后的列执行b树查找.理论上PostgreSQL仍然可以进行b树索引查找,如果它可以证明表达式保留了所有情况的排序,就像extract(epoch from ts)......一样,但目前优化器不知道如何做到这一点.即使它可以,extract(day from ...)也不保留输入的排序,因为"较低"的时间戳可以具有更高的"日",因此不能使用b树查找.

ts BETWEEN a AND b只是写作ts >= a和写作的简写ts <= b.两者都是b树可索引操作.

可以在表达式上创建新的b树索引,例如

create index mytable_ts_day on mytable(extract(day from ts))
Run Code Online (Sandbox Code Playgroud)

然后,此索引用于匹配表达式extract(day from ts) = 9,或者表达式为b-tree可索引的任何其他运算符.但是,这意味着您必须维护另一个索引,该索引具有执行每个插入和更新的成本,并且竞争缓存空间.