我正在执行更新,我需要一个tstzrange变量完全相等。修改了大约 100 万行,查询需要大约 13 分钟。的结果EXPLAIN ANALYZE可以在这里看到,实际结果与查询计划器估计的结果有很大的不同。问题是索引扫描t_range期望返回单行。
这似乎与范围类型的统计信息与其他类型的统计信息的存储方式有关。pg_stats查看列的视图,n_distinct是 -1,其他字段(例如most_common_vals,most_common_freqs)为空。
但是,必须在t_range某处存储统计信息。我在 t_range 上使用 'within' 而不是完全相等的极其相似的更新需要大约 4 分钟才能执行,并且使用了完全不同的查询计划(请参阅此处)。第二个查询计划对我来说很有意义,因为将使用临时表中的每一行和历史表的很大一部分。更重要的是,查询规划器为 上的过滤器预测了近似正确的行数t_range。
的分布t_range有点不寻常。我正在使用这个表来存储另一个表的历史状态,并且对另一个表的更改在大转储中同时发生,因此没有很多不同的t_range. 以下是与 的每个唯一值对应的计数t_range:
t_range | count
-------------------------------------------------------------------+---------
["2014-06-12 20:58:21.447478+00","2014-06-27 07:00:00+00") | 994676
["2014-06-12 20:58:21.447478+00","2014-08-01 01:22:14.621887+00") | 36791
["2014-06-27 07:00:00+00","2014-08-01 07:00:01+00") | 1000403
["2014-06-27 07:00:00+00",infinity) | 36791
["2014-08-01 07:00:01+00",infinity) | 999753
Run Code Online (Sandbox Code Playgroud)
t_range上面distinct的计数是完整的,所以基数是~3M(其中~1M会受到任一更新查询的影响)。
为什么查询 1 的性能比查询 2 …
postgresql performance postgresql-9.3 range-types query-performance
有人可以解释这种神秘的 Postgres 行为吗?我正在psql命令行执行以下查询。
mydb=> select '20150526' > '2015-05-25';
-[ RECORD 1 ]
?column? | t
mydb=> select '20150526' > '2015-05-26';
-[ RECORD 1 ]
?column? | f
mydb=> select '20150526' > '2015-05-27';
-[ RECORD 1 ]
?column? | f
Run Code Online (Sandbox Code Playgroud)
如果 Postgres 实际上是直接比较字符串,则这三个值要么为真,要么为假,这取决于字符排序的定义方式。这似乎表明 Postgres 试图在比较之前将字符串转换为日期,大概是基于对格式的一些启发。然而:
mydb=> select '20150526' < '2015-05-27';
-[ RECORD 1 ]
?column? | t
mydb=> select '20150526' < '2015-05-26';
-[ RECORD 1 ]
?column? | t
mydb=> select '20150526' < '2015-05-25';
-[ RECORD 1 ]
?column? …Run Code Online (Sandbox Code Playgroud)