oracle java 绑定变量的值_Oracle SQL调优之绑定变量用法简介
最近在看《基于Oracle的SQL优化一书》,并做了笔记,作者的个人博客:http://www.dbsnake.net/
@
一、SQL执行过程简介
继上一篇博客Oracle的cursor学习笔记:Oracle的游标Cursor原理简介,再介绍oracle的绑定变量
介绍绑定变量之前,先介绍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批量绑定变量
例子来自《基于Oracle的SQL优化》一书,要实现的的是批量绑定变量,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代码里使用绑定变量
不用绑定变量的写法:
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();
批量绑定变量写法:
此例子来自《基于Oracle的SQL优化》一书:
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();
oracle java 绑定变量的值_Oracle SQL调优之绑定变量用法简介相关推荐
- oracle sql 执行计划分析_Oracle SQL调优系列之看懂执行计划explain
1.文章写作前言简介 SQL调优系列博客链接:SQL调优专栏 之前曾经拜读过<收获,不止sql调优>一书,此书是国内DBA写的一本很不错的调优类型的书,是一些很不错的调优经验的分享.虽然读 ...
- oracle sql 分区查询语句_Oracle SQL调优之分区表
一.分区表简介 分区通过让您将它们分解为更小且更易于管理的分区(称为分区)来解决支持非常大的表和索引的关键问题.不需要修改SQL查询和DML语句以访问分区表.但是,在定义分区之后,DDL语句可以访问和 ...
- Oracle SQL调优系列之no_unnest和unnest用法简介
Oracle调优之no_unnest和unnest用法简介 本博客介绍Oracle SQL调优的一种常用也是很实用的方法,也即/*+no_unnest */和/*+ unnest*/,介绍Oracle ...
- 11g新特性-自动sql调优(Automatic SQL Tuning)
11g新特性-自动sql调优(Automatic SQL Tuning) 在Oracle 10g中,引进了自动sql调优特性.此外,ADDM也会监控捕获高负载的sql语句. 在Oracle 11g中, ...
- Oracle中SQL调优(SQL TUNING)之最权威获取SQL执行计划大全
该文档为根据相关资料整理.总结而成,主要讲解Oracle数据库中,获取SQL语句执行计划的最权威.最正确的方法.步骤,此外,还详细说明了每种方法中可选项的意义及使用方法,以方便大家和自己日常工作中查阅 ...
- 【C 语言】指针间接赋值 ( 直接修改 和 间接修改 指针变量 的值 | 在函数中 间接修改 指针变量 的值 | 在函数中 间接修改 外部变量 的原理 )
文章目录 一.直接修改 和 间接修改 指针变量 的值 二.在函数中 间接修改 指针变量 的值 三.在函数中 间接修改 外部变量 的原理 一.直接修改 和 间接修改 指针变量 的值 直接修改 指针变量 ...
- oracle避免回表,请教大家: 经常在sql调优过程中提到避免“回表”,具体是指什么意思???3Q...
你的位置: 问答吧 -> Oracle -> 问题详情 请教大家: 经常在sql调优过程中提到避免"回表",具体是指什么意思???3Q 如题,不甚感激!!!! [ 本帖 ...
- 交换两个变量的值,不使用第三个变量的四种法方
交换两个变量的值,不使用第三个变量的四种法方 通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换.代码如下: int a,b; a=10; b=15; int t; t=a; a= ...
- oracle trim 性能,ORACLE sql调优之记录一次trim函数引发的大表全表扫描
2017年8月14日,一地市oracle相关的调度程序ETL抽取速度奇慢,sql语句每次执行平均时间要9秒左右,如果所示: 该调度过程涉及的sql语句如下: select count(*) from ...
最新文章
- squid+iptables实现透明代理
- python的git_Pygit: 用Python实现Git的功能
- web of science patent search
- 2021-03-01 英文写作中的“许多”
- C语言中指针的初始化和赋值
- .net调用c++方法时如何释放c++中分配的内存_C/C++编程笔记:C语言编程知识要点总结!大一C语言知识点(全)...
- php链表和联表的区别,PHP_浅谈PHP链表数据结构(单链表),链表:是一个有序的列表,但 - phpStudy...
- attention机制_简析Attention机制—优缺点,实现,应用
- [unity3d]再次修改socket聊天,完美的服务器端
- 常见英文缩写 (持续更新……)
- Android学习系列(4)--App自适应draw9patch不失真背景
- 计算机网络原理 谢希仁(第8版)第二章习题答案
- 在微信小程序中打造 MQTT 连接测试工具
- Book04--修改软件的艺术:构建易维护代码的9条最佳实践
- html根据出生日期计算星座,0047 JavaScript实现根据输入日期计算所属星座
- 银行柜员网申计算机水平要求高吗,银行笔试通过率:看你网申如何?
- 传统医美身处风口浪尖,互联网医美如何拯救?
- 一起来云赏月把!three.js实现vr赏月!
- 论文阅读——INSIDER:Designing In-Storage Computing System for Emerging High-Performance Drive
- 小猪佩奇代码 Python