首页 > 解决方案 > 为什么在进行函数调用时索引不用于 tstarange 字段?

问题描述

对于这种情况,何时timestamp使用常量索引:

explain analyse select * from order_bt where '2019-03-01'::timestamptz <@ sys_period;
                                                                   QUERY PLAN             
------------------------------------------------------------------------------------------
 Index Scan using order_id_sys_period_app_period_excl on order_bt  (cost=0.15..8.17 rows=1
   Index Cond: ('2019-03-01 00:00:00+02'::timestamp with time zone <@ sys_period)
 Planning time: 0.185 ms
 Execution time: 0.085 ms
(4 rows)

但是当我调用timestamp不使用返回索引的函数时:

explain analyse select * from order_bt where sys_time() <@ sys_period;
                                                 QUERY PLAN                               
------------------------------------------------------------------------------------------
 Seq Scan on order_bt  (cost=0.00..1050.78 rows=19 width=136) (actual time=0.099..36.676 r
   Filter: (sys_time() <@ sys_period)
   Rows Removed by Filter: 927
 Planning time: 0.142 ms
 Execution time: 37.065 ms
(5 rows)

第二次查询的函数调用有什么问题?如何解释PG使用索引?

标签: postgresql

解决方案


大概发现

STABLE 函数不能修改数据库,并保证在给定单个语句中所有行的相同参数的情况下返回相同的结果。此类别允许优化器将函数的多次调用优化为单个调用。特别是,在索引扫描条件中使用包含此类函数的表达式是安全的。(由于索引扫描只会评估比较值一次,而不是每行一次,因此在索引扫描条件下使用 VOLATILE 函数是无效的。

我的功能是volatile


推荐阅读