Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么常量的类型转换会破坏查询性能_Sql_Postgresql_Performance_Indexing_Query Planner - Fatal编程技术网

Sql 为什么常量的类型转换会破坏查询性能

Sql 为什么常量的类型转换会破坏查询性能,sql,postgresql,performance,indexing,query-planner,Sql,Postgresql,Performance,Indexing,Query Planner,测试表和索引(PostgreSQL 12.1): 在第一个查询中,一切正常,使用适当的索引“ind”: 为什么使用“2020-02-08”(已经是文本)的“::text”类型转换查询性能非常低 explain (analyze, buffers) SELECT * FROM t WHERE ('2020-02-08'::text)::date IS NULL OR dt > '2020-02-08' ORDER BY dt LIMIT 1 "Limit (cost=0

测试表和索引(PostgreSQL 12.1):

在第一个查询中,一切正常,使用适当的索引“ind”:

为什么使用“2020-02-08”(已经是文本)的“::text”类型转换查询性能非常低

explain (analyze, buffers)
SELECT *
FROM t
WHERE
   ('2020-02-08'::text)::date IS NULL
   OR
   dt > '2020-02-08'
ORDER BY dt
LIMIT 1

"Limit  (cost=0.29..0.44 rows=1 width=8) (actual time=45.306..45.307 rows=1 loops=1)"
"  Buffers: shared hit=6232"
"  ->  Index Only Scan using ind on t  (cost=0.29..561.28 rows=3658 width=8) (actual time=45.304..45.304 rows=1 loops=1)"
"        Filter: ((('2020-02-08'::cstring)::date IS NULL) OR (dt > '2020-02-08 00:00:00+05'::timestamp with time zone))"
"        Rows Removed by Filter: 6367"
"        Heap Fetches: 6368"
"        Buffers: shared hit=6232"
"Planning Time: 0.348 ms"
"Execution Time: 45.343 ms"

非空常量何时为空?看起来pg意识到它不是在第一种情况下,并且省略了过滤器中的所有数据类型转换,但是在第二种情况下它没有(因为双重转换?),因此进行了大量的数据转换,这将引入一些额外的工作。您认为可以接受哪种毫秒的速度减慢?@CaiusJard如果用int列而不是timestamp重写整个示例,那么两个查询都能正常工作,所以问题不是双重转换-::text::int双重转换工作正常。我认为您犯了逻辑错误。您认为双转换::text::int可以很好地工作,因此::text::date也可以。但这些转换并不相同。
explain (analyze, buffers)
SELECT *
FROM t
WHERE
   ('2020-02-08')::date IS NULL
   OR
   dt > '2020-02-08'
ORDER BY dt
LIMIT 1

"Limit  (cost=0.29..0.37 rows=1 width=8) (actual time=0.186..0.188 rows=1 loops=1)"
"  Buffers: shared hit=3"
"  ->  Index Only Scan using ind on t  (cost=0.29..303.75 rows=3627 width=8) (actual time=0.184..0.184 rows=1 loops=1)"
"        Index Cond: (dt > '2020-02-08 00:00:00+05'::timestamp with time zone)"
"        Heap Fetches: 1"
"        Buffers: shared hit=3"
"Planning Time: 2.365 ms"
"Execution Time: 0.239 ms"
explain (analyze, buffers)
SELECT *
FROM t
WHERE
   ('2020-02-08'::text)::date IS NULL
   OR
   dt > '2020-02-08'
ORDER BY dt
LIMIT 1

"Limit  (cost=0.29..0.44 rows=1 width=8) (actual time=45.306..45.307 rows=1 loops=1)"
"  Buffers: shared hit=6232"
"  ->  Index Only Scan using ind on t  (cost=0.29..561.28 rows=3658 width=8) (actual time=45.304..45.304 rows=1 loops=1)"
"        Filter: ((('2020-02-08'::cstring)::date IS NULL) OR (dt > '2020-02-08 00:00:00+05'::timestamp with time zone))"
"        Rows Removed by Filter: 6367"
"        Heap Fetches: 6368"
"        Buffers: shared hit=6232"
"Planning Time: 0.348 ms"
"Execution Time: 45.343 ms"