如何使用参数/变量并一起解释

Jua*_*eza 1 sql postgresql performance sql-execution-plan pgadmin

我的函数只有一个参数carAzimuth

CREATE OR REPLACE FUNCTION map.get_near_link(x numeric, y numeric, carAzimuth numeric)
Run Code Online (Sandbox Code Playgroud)

里面我有一些计算和这个查询

SELECT *
FROM map.vzla_seg S
WHERE
    S.azimuth > carAzimuth - 30  and   
    S.azimuth < carAzimuth + 30  or
    S.azimuth < carAzimuth - 330 or 
    S.azimuth > carAzimuth + 330;
Run Code Online (Sandbox Code Playgroud)

我想分析查询性能。所以我必须将变量替换为常量。并且工作正常,并向EXPLAIN PLAN我展示正在使用正确的索引。

EXPLAIN ANALYZE    
 SELECT *
 FROM map.vzla_seg S
 WHERE
    S.azimuth > 345 - 30  and   
    S.azimuth < 345 + 30  or
    S.azimuth < 345 - 330 or 
    S.azimuth > 345 + 330;
Run Code Online (Sandbox Code Playgroud)

但如果想测试不同的值,改变每个变量是很麻烦的。那么如果你尝试

EXPLAIN ANALYZE  
  WITH param(carAzimuth) as (select 345) 
  SELECT *
  FROM vzla_seg S, param 
  WHERE
      S.azimuth > carAzimuth- 30 and   
      S.azimuth < carAzimuth + 30 or
      S.azimuth < carAzimuth - 330 or 
      S.azimuth > carAzimuth + 330;
Run Code Online (Sandbox Code Playgroud)

有效,但停止使用索引并更改为FULL SCAN

"Nested Loop  (cost=0.01..208990.91 rows=2328905 width=4) (actual time=0.146..4138.882 rows=642115 loops=1)"
"  Join Filter: (((s.azimuth > (p.carazimuth - 30)) AND (s.azimuth < (p.carazimuth + 30))) OR (s.azimuth < (p.carazimuth - 330)) OR (s.azimuth > (p.carazimuth + 330)))"
"  Rows Removed by Join Filter: 3207719"
"  CTE parameter"
"    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)"
"  ->  CTE Scan on parameter p  (cost=0.00..0.02 rows=1 width=4) (actual time=0.009..0.012 rows=1 loops=1)"
"  ->  Seq Scan on vzla_seg s  (cost=0.00..93496.22 rows=3849822 width=4) (actual time=0.072..1380.356 rows=3849834 loops=1)"
"Total runtime: 4253.113 ms"
Run Code Online (Sandbox Code Playgroud)

那么有没有一种方法可以创建我的变量并在没有函数的情况下在解释中使用它?

我使用 pgAdmin 上的 SQL 编辑器来运行我的查询。

Pav*_*ule 5

您假设 soWITH子句是等效函数是错误的。子句与公共表表达式WITH相关,与函数零关系。当您想从功能中查看计划时,有两种可能性:

\n\n
    \n
  1. 使用auto_explain扩展 - 使用此扩展,您可以记录任何嵌套计划 - 只需启用一个选项auto_explain.log_nested_statements

  2. \n
  3. 您可以使用准备好的语句 - 任何 SQL 都会透明地转换为 PLpgSQL 中的准备好的语句。

    \n\n
    prepare xx(int) as select * from foo where a = $1::text;\nexplain analyze execute xx(10);\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82                                          QUERY PLAN                                           \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 Seq Scan on foo  (cost=0.00..21.00 rows=4 width=64) (actual time=0.019..0.019 rows=0 loops=1) \xe2\x94\x82\n\xe2\x94\x82   Filter: (a = \'10\'::text)                                                                   \xe2\x94\x82\n\xe2\x94\x82   Rows Removed by Filter: 2                                                                   \xe2\x94\x82\n\xe2\x94\x82 Execution time: 0.052 ms                                                                      \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
    Run Code Online (Sandbox Code Playgroud)\n\n

    注意:前 5 次执行计划始终是新鲜的(不会重用,并且会一次又一次地生成)。执行5次后,计划可以通用并重用。请参阅相关文档中的计划缓存章节。

  4. \n
\n