SQL调优之绑定变量用法简介

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: SQL调优之绑定变量用法简介

一、SQL执行过程简介

介绍绑定变量之前,先介绍SQL执行过程和硬解析的概念:

执行sql的过程,会将sql的文本进行hash运算,得到对象的hash值,然后拿hash值,去Hash Buckets里遍历缓存对象句柄链表,找到对应的缓存对象句柄,然后就可以得到缓存对象句柄里对应sql执行计划、解析树等对象,所以执行相同的sql第二次执行时是会比较快的,因为不需要解析获取执行计划,解析树等对象,如果找不到库缓存对象句柄,就需要重新解析,这个过程解析过多,容易造成硬解析问题

硬解析:是指Oracle在执行目标SQL时,在库缓存中找不到可以重用的解析树和执行计划,而不得不从头开始解析目标SQL并生成相应的Parent Cursor和Child Cursor的过程。

软解析:是指Oracle在执行目标SQL时,在Library Cache中找到了匹配的Parent Cursor和Child Cursor,并将存储在Child Cursor中的解析树和执行计划直接拿过来重用,无须从头开始解析的过程。

ok,上面是SQL执行过程的简单介绍,由此可知,假如sql执行过程,在共享池里找不到执行计划、解析树等就会重现解析sql,生成执行计划和解析树等,这个过程是比较耗时间的,所以要想办法尽量不要重现解析sql,需要执行计划直接去共享池拿已经生成的

举个例子,select * from sys_user where userid='u10001';select * from sys_user where userid='u10002';,这两个很类似的sql在执行过程,生成的执行计划很有可能是不一样的,也就是说第一条sql执行后,第二条sql继续执行,假如发现找不到对应执行计划,就会再解析sql,重现生成session cursor和一对shared cursor(parent cursor和child cursor)

然后,我们不想重新解析sql,有什么方法?方法就是用绑定变量的方法

二、绑定变量典型用法

2.1、在SQL中绑定变量

绑定变量的典型用法就是用 :variable_name的形式,variable_name是自定义的变量名称,variabl_name可以是字母、数字或者字母和数字的组合

ok,上面的那种类型的sql,就可以用一条带绑定变量的sql来表示:

select * from sys_user where userid = :u;

这样这种类型的一堆sql都只会解析一次,不用每条sql都解析一遍,可以很好的提高系统处理能力

ok,举个例子说明

环境准备:

/* 随便建一张表*/
create table t as select * from dba_objects;

注意,这些脚本只能在sqlplus或者PLSQL客户端的命令窗口执行

/* 定义绑定变量vid */
SQL> variable vid number;
/* 给绑定变量赋值为2 */
SQL> exec :vid := 2;

在sqlplus或者PLSQL客户端的命令窗口执行

/* 通过绑定变量查询 */
SQL> select * from t where object_id = :vid;
 /*通过性能视图查询SQL解析情况*/
select a.*, b.name
  from v$sesstat a, v$statname b
 where a.statistic# = b.statistic#
   and a.sid = (select distinct sid from v$mystat)
   and b.name like '%parse%';
/* 去共享池查询一下这种类型的SQL信息*/
select sql_text, parse_calls, executions
  from v$sql
 where sql_text like 'select * from t where object_id=%';
/* 通过共享池查询查询最慢的10条sql*/
SELECT *
  FROM (select PARSING_USER_ID,
               EXECUTIONS,
               SORTS,
               COMMAND_TYPE,
               DISK_READS,
               sql_text
          FROM v$sqlarea
         order BY disk_reads DESC)
 where ROWNUM < 10;

2.2、在PL/SQL中使用绑定变量

/* SQL语句使用绑定变量*/
declare
  vc_empname varchar2(10);
begin
  execute immediate 'select ename from t_emp where empno = :1'
    into vc_empname
    using 7369;
  dbms_output.put_line(vc_empname);
end;
/

往t_emp表写入一条数据,并统计是否执行成功,返回数值

/*DML语句使用绑定变量*/
declare
 vc_sql varchar2(2000);
 vc_number number;
begin 
  vc_sql := 'insert into t_emp(empno,ename,job) values(:1,:2,:3)';
  execute immediate vc_sql using 7990,'SMITH','HR';
  vc_number := sql%rowcount;
  dbms_output.put_line(to_char(vc_number));
  commit;
end;
/

所以绑定变量在pl/sql里的核心语法为:

execute immediate [sql语句] using [变量]

2.3、PL/SQL批量绑定变量

例子来自http://www.wityx.com/database,要实现的的是批量绑定变量,fetch关键字,将empno大于7900的职员信息打印出来

declare
 cur_emp sys_refcursor;
 vc_sql varchar2(2000);
 type namelist is table of varchar2(10);
 enames namelist;
 CN_BATCH_SIZE constant pls_integer := 1000;
 begin
  vc_sql:= 'select ename from t_emp where empno > :1';
  open cur_emp for vc_sql using 7900;
  loop 
    fetch cur_emp bulk collect into enames limit CN_BATCH_SIZE;
    for i in 1..enames.count loop
     dbms_output.put_line(enames(i));
    end loop;
    exit when enames.count < CN_BATCH_SIZE;
    end loop;
    close cur_emp;
 end;
 

2.4、Java代码里使用绑定变量

参考http://www.wityx.com/database/

不用绑定变量的写法:

String empno = '7369';
String query_sql = 'select ename from t_emp where empno = 7369 '; 
stmt = con.prepareStatement( query_sql );
stmt.executeQuery();

使用绑定变量的写法:

String empno = 'xxxxx';
String query_sql = 'select ename from t_emp where empno = ? '; //嵌入绑定变量
stmt = con.prepareStatement( query_sql );
stmt.setString(1, empno ); //为绑定变量赋值
stmt.executeQuery();

批量绑定变量写法: 此例子来自http://www.wityx.com

String vc_sql = 'update t_emp set sal = ? where empno = ?';
pstmt = connection.prepareStatement(dml);
pstmt.clearBatch();
for (int i = 0; i < UPDATE_COUNT; ++ i) {
  pstmt.setInt(1, generateEmpno(i));
  pstms.setInt(2, generateSal(i));
  pstmt.addBatch();
}
pstmt.executeBatch();
connection.commit();


相关文章
|
4月前
|
SQL 数据库 开发者
MSSQL性能调优实战技巧:索引优化、SQL语句微调与并发控制策略
在Microsoft SQL Server(MSSQL)的管理与优化中,性能调优是一项复杂但至关重要的任务
|
2月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
2月前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
539 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
1月前
|
SQL Oracle 关系型数据库
Oracle SQL:了解执行计划和性能调优
Oracle SQL:了解执行计划和性能调优
52 1
|
2月前
|
SQL 分布式计算 数据库
SQL调优总结
数据库表的规范化和反规范化设计,设计合适的字段数据类型……
44 8
|
2月前
|
SQL 存储 安全
SQL Server用法
SQL Server用法
63 1
|
2月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
44 1
|
3月前
|
Java XML Maven
跨越时代的飞跃:Struts 2 升级秘籍——从旧版本无缝迁移到最新版,焕发应用新生!
【8月更文挑战第31天】随着软件技术的发展,Struts 2 框架也在不断更新。本文通过具体案例指导开发者如何从旧版平滑升级到 Struts 2.6.x。首先更新 `pom.xml` 中的依赖版本,并执行 `mvn clean install`。接着检查 `struts.xml` 配置,确保符合新版本要求,调整包扫描器等设置。审查 Action 类及其注解,检查配置文件中的弃用项及插件。更新自定义拦截器实现,并验证日志配置。最后,通过一系列测试确保升级后的系统正常运行。通过这些步骤,可以顺利完成 Struts 2 的版本升级,提升应用的安全性和性能。
203 0
|
3月前
|
Java 开发者 前端开发
Struts 2、Spring MVC、Play Framework 上演巅峰之战,Web 开发的未来何去何从?
【8月更文挑战第31天】在Web应用开发中,Struts 2框架因强大功能和灵活配置备受青睐,但开发者常遇配置错误、类型转换失败、标签属性设置不当及异常处理等问题。本文通过实例解析常见难题与解决方案,如配置文件中遗漏`result`元素致页面跳转失败、日期格式不匹配需自定义转换器、`&lt;s:checkbox&gt;`标签缺少`label`属性致显示不全及Action中未捕获异常影响用户体验等,助您有效应对挑战。
88 0
|
3月前
|
SQL 监控 关系型数据库
SQL性能监控与调优工具的神奇之处:如何用最佳实践选择最适合你的那一个,让你的数据库飞起来?
【8月更文挑战第31天】在现代软件开发中,数据库性能监控与调优对应用稳定性至关重要。本文对比了数据库内置工具、第三方工具及云服务工具等几种常用SQL性能监控与调优工具,并通过示例代码展示了如何利用MySQL的EXPLAIN功能分析查询性能。选择最适合的工具需综合考虑功能需求、数据库类型及成本预算等因素。遵循了解工具功能、试用工具及定期维护工具等最佳实践,可帮助开发者更高效地管理和优化数据库性能,迎接未来软件开发中的挑战与机遇。
53 0