PostgreSQL查看带有绑定变量SQL的通用方法详解

当我们在PostgreSQL中分析一些历史的SQL问题时,往往看到的SQL都是带有绑定变量的。而对于pg,我们没法像Oracle一样通过例如dba_hist_sqlbind之类的视图去获取历史的绑定变量值。不仅如此,对于这些带有绑定变量的SQL,我们甚至没法像在Oracle中一样获取一个预估的执行计划。

在pg中使用explain去执行则会报错:

bill=# explain select * from t1 where id = $1 and info = $2;
ERROR:  there is no parameter $1
LINE 1: explain select * from t1 where id = $1 and info = $2;

我们似乎只能去通过带入值去获取相应的执行计划了,这对于那些绑定变量很多的SQL来说无疑是十分繁琐的。那有没有什么方法能像Oracle中那样,即使是有绑定变量的SQL,在plsql developer中一个F5就显示了预估的执行计划呢?

我们可以使用prepare语句来实现想要的功能。

例如:

bill=# prepare p1 as select * from t1 where id = $1 and info = $2;
PREPARE

可以看到上面的SQL有两个变量,那么我们在不知道变量的情况下怎么去获取执行计划呢?

可以用null,因为这适用于任何数据类型。

但事实往往没有那么乐观:

bill=# explain execute p1(null,null);
                QUERY PLAN
------------------------------------------
 Result  (cost=0.00..0.00 rows=0 width=0)
   One-Time Filter: false
(2 rows)

可以看到优化器十分聪明,知道查询的结果中没有行,甚至都不去扫描表了。对于这种情况,我们只需要执行5次,让其生成generic plan。

bill=# explain execute p1(null,null);
                            QUERY PLAN
-------------------------------------------------------------------
 Index Scan using t1_pkey on t1  (cost=0.15..2.77 rows=1 width=36)
   Index Cond: (id = $1)
   Filter: (info = $2)
(3 rows)

当然,如果你的版本是pg12之后的,那么就没必要这么麻烦了,直接设置plan_cache_mode来控制就好。

bill=# prepare p1 as select * from t1 where id =$1 and info = $2;
PREPARE
bill=# set plan_cache_mode = force_generic_plan;
SET
bill=# explain execute p1(null,null);
                            QUERY PLAN
-------------------------------------------------------------------
 Index Scan using t1_pkey on t1  (cost=0.15..2.77 rows=1 width=36)
   Index Cond: (id = $1)
   Filter: (info = $2)
(3 rows)

如果你的版本是pg12之前的,那么只能执行5次然后等到第6次生成通用的执行计划了。当然还有点需要注意的,如果估计成本高于先前执行的平均成本时就不会选择通用计划了,所以我们可以人为的控制前5次的平均成本,让其达到一个很高的值,这一点我们可以增加cpu_operator_cost的值来实现。

bill=# prepare p1 as select * from t1 where id =$1 and info = $2;
bill=# set local cpu_operator_cost=999999; --设置成一个很大的值
bill=# explain execute p1(null,null);
bill=# explain execute p1(null,null);
bill=# explain execute p1(null,null);
bill=# explain execute p1(null,null);
bill=# explain execute p1(null,null);
bill=# explain execute p1(null,null); --生成通用执行计划

到此这篇关于PostgreSQL查看带有绑定变量SQL的通用方法详解的文章就介绍到这了,更多相关PostgreSQL绑定变量SQL内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • postgresql 存储函数调用变量的3种方法小结

    一.假设有表student,字段分别有id,remark,name等字段. 二.写一个存储函数,根据传过去的变量ID更新remark的内容. 调用该存储函数格式如下: select update_student(1); 三.存储函数示例如下: CREATE OR REPLACE FUNCTION public.update_student(id integer) RETURNS text AS $BODY$ declare sql_str_run text; BEGIN /* --method

  • postgresql SQL语句变量的使用说明

    一般变量使用我们都是放在函数里面,这里开发需求,要在SQL直接使用变量,方便查找一些问题,比如时间变量,要根据时间进行筛选 这里有三种方法可以实现 1.psql命令使用变量 表数据如下: hank=> select * from tb2; c1 | c2 | c3 ----+-------+---------------------------- 1 | hank | 2018-02-06 10:08:00.787503 2 | dazui | 2018-02-06 10:08:08.54248

  • PostgreSQL 正则表达式替换-使用变量方式

    ###不定期更新 把AAAA替换为A-A-A-A- javascript alert('AAAA'.replace(/([A]{1})/g,"$1-")); ()中的内容用变量$1 $2 $n代替 PostgreSQL select regexp_replace('AAAAAAAAAAAAAAAAAAAAAA','([A-Z]{1})','\1-','g') ()中的内容用变量\1 \2 \n代替 获取大括号中的内容 select f1[1] from regexp_matches('

  • PostgreSQL查看带有绑定变量SQL的通用方法详解

    当我们在PostgreSQL中分析一些历史的SQL问题时,往往看到的SQL都是带有绑定变量的.而对于pg,我们没法像Oracle一样通过例如dba_hist_sqlbind之类的视图去获取历史的绑定变量值.不仅如此,对于这些带有绑定变量的SQL,我们甚至没法像在Oracle中一样获取一个预估的执行计划. 在pg中使用explain去执行则会报错: bill=# explain select * from t1 where id = $1 and info = $2; ERROR: there i

  • java执行SQL语句实现查询的通用方法详解

    完成SQL查询 并将查询结果放入Vector容器,以便其他程序使用 /* * 执行sql查询语句 */ public static <T> Vector<T> executeQuery(Class<T> clazz, String sql, Object... args) { Connection conn = null; PreparedStatement preparedstatement = null; ResultSet rs = null; Vector<

  • C++中使用function和bind绑定类成员函数的方法详解

    定义一个普通的类 class Test1{ public: void fun(int val){ cout<<"hello world "<<val<<endl; } }; 开始第一个测试 int main(){ Test1 t; function<void(int)> pf = std::bind(&Test1::fun,t,2); pf(4); // return 0; } 输出的值是2,说明pf传进去的4并没有什么用,在bi

  • Linux查看日志文件写入速度的4种方法详解

    目录 简介 使用dd 使用pv 使用cv命令 编写小脚本 举一反三 简介 有时,我们需要查看某个文件的增长速度,如日志文件,以此来感受系统的负载情况,因为一般情况下,日志写入越快,说明系统负载越重. 本文就来介绍下Linux中查看日志增长速度的几种方法,如下: 使用dd 首先要介绍的是dd,因为dd命令几乎所有主流发行版都自带,无需额外安装,如下: $ tail -F app.log | dd of=/dev/null status=progress 3875840 bytes (3.9 MB)

  • 6种查看Linux进程占用端口号的方法详解

    对于 Linux 系统管理员来说,清楚某个服务是否正确地绑定或监听某个端口,是至关重要的.如果你需要处理端口相关的问题,这篇文章可能会对你有用. 端口是 Linux 系统上特定进程之间逻辑连接的标识,包括物理端口和软件端口.由于 Linux 操作系统是一个软件,因此本文只讨论软件端口.软件端口始终与主机的 IP 地址和相关的通信协议相关联,因此端口常用于区分应用程序.大部分涉及到网络的服务都必须打开一个套接字来监听传入的网络请求,而每个服务都使用一个独立的套接字. 套接字是和 IP 地址.软件端

  • php防止sql注入的方法详解

    一.什么是SQL注入式攻击? 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击.常见的SQL注入式攻击过程类如:   ⑴ 某个ASP.NET Web应用有一个登录页面,这个登录页面控制着用户是否有权访问应用,它要求用户输入一个名称和密码.     ⑵ 登录页面中输入的内容将直接用来构造动态的S

  • Python中防止sql注入的方法详解

    前言 大家应该都知道现在web漏洞之首莫过于sql了,不管使用哪种语言进行web后端开发,只要使用了关系型数据库,可能都会遇到sql注入攻击问题.那么在Python web开发的过程中sql注入是怎么出现的呢,又是怎么去解决这个问题的? 当然,我这里并不想讨论其他语言是如何避免sql注入的,网上关于PHP(博主注:据说是世界上最屌的语言)防注入的各种方法都有,Python的方法其实类似,这里我就举例来说说. 起因 漏洞产生的原因最常见的就是字符串拼接了,当然,sql注入并不只是拼接一种情况,还有

  • MySQL设置global变量和session变量的两种方法详解

    1.在MySQL中要修改全局(global)变量,有两种方法: 方法一,修改my.ini配置文件,如果要设置全局变量最简单的方式是在my.ini文件中直接写入变量配置,如下图所示.重启数据库服务就可以使全局变量生效. 我们打开几个mysql命令行,可以看到所有会话中的变量都生效了,如图 方法二,在不修改配置文件的基础上,使用关键字global设置全局变量 set global autocommit=1; 将autocommit变量的值设置为ON 需要注意的是,使用此方法对global全局变量的设

  • C语言中判断int,long型等变量是否赋值的方法详解

    当然,如果你不赋值给局部变量,这样会导致整个程序的崩溃,因为,它的内容被系统指向了垃圾内存.下面我们看一段代码: 复制代码 代码如下: #include <stdio.h>#include <string.h>#include <stdlib.h>int globle_value;int my_sum(int value1, int value2);long my_sub(long value1, long value2);int main(void){ int aut

  • Windows系统彻底卸载SQL Server通用方法(推荐!)

    目录 前言 一.停止 SQL Server 服务 二.卸载 SQL Server 数据库 三.删除 SQL Server 相关文件 四.删除 SQL Server 相关注册表 五.重启电脑 总结 前言 无论什么时候,SQL Server 的安装和卸载都是一件让我们头疼的事情.因为不管是 SQL Server 还是 MySQL 的数据库,当我们在使用数据库时因为未知原因出现问题,想要卸载重装时,如果数据库卸载不干净,就会导致数据库重装失败.所以学会卸载 SQL Server 还是很重要的,本篇文章

随机推荐