通过绑定变量优化OLTP系统性能

之前给南京某客户优化一套OLTP数据库,其数据库中在某个时间段,会执行大量结构非常相似的查询语句,造成shared_pool被大量占用,导致数据库性能下降。碰到这种情况,其实最佳优化方案,就是让应用厂商修改相应代码,通过增加绑定变量,来有效减少相似SQL语句执行时的硬解析数,降低对shared_pool的消耗。下面来做一个关于绑定变量的测试:

1.创建测试用户并赋予权限

[[email protected] ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Sun Sep 14 14:47:32 2014

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

--创建用户

SQL> create user zlm identified by zlm;

User created.

--赋权限

SQL> grant dba to zlm;

Grant succeeded.

--创建表空间

SQL> create tablespace zlm datafile ‘/u01/app/oracle/oradata/zlm11g/zlm01.dbf‘ size 100m reuse autoextend on next 10m maxsize 1G extent management
local segment space management auto;

Tablespace created.

--设置缺省表空间

SQL> alter user zlm default tablespace zlm;

User altered.

--连接用户

SQL> conn zlm/zlm

Connected.

--创建测试表

SQL> create table t1 as select object_id,object_name from dba_objects;

Table created.

--创建索引

SQL> create index inx_t1_id on t1(object_id);

Index created.

--收集表的统计信息

SQL> exec dbms_stats.gather_table_stats(‘ZLM‘,‘T1‘,estimate_percent=>100,cascade=>true);

PL/SQL procedure successfully completed.

2.不使用绑定变量的情况

--设置tracle文件标识符

SQL> alter session set tracefile_identifier=‘ZLM01‘;

Session altered.

--开启sql_trace

SQL> alter session set sql_trace=true;

Session altered.

--执行PL/SQL程序段

SQL> begin

2  for s in 1..10000

3  loop

4  execute immediate ‘select * from t1 where object_id=‘||s;

5  end loop;

6  end;

7  /

PL/SQL procedure successfully completed.

--关闭sql_trace

SQL> alter session set sql_trace=false;

Session altered.

SQL> !

[[email protected] ~]$ cd /u01/app/oracle/diag/rdbms/zlm11g/zlm11g/trace/

[[email protected] trace]$ ll -lrth | grep ZLM01.trc

-rw-r----- 1 oracle oinstall 7.3M Sep 14 15:00 zlm11g_ora_14341_ZLM01.trc

[[email protected] trace]$ tkprof zlm11g_ora_14341_ZLM01.trc /home/oracle/zlm01.log

TKPROF: Release 11.2.0.3.0 - Development on Sun Sep 14 15:05:46 2014

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

[[email protected] trace]$

--查看用tkprof格式化后的日志zlm01.log最后一段

OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse    10000      6.26       6.53          0          0          0           0

Execute  10000      0.23       0.26          0          0          0           0

Fetch        0      0.00       0.00          0          0          0           0

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total    20000      6.50       6.79          0          0          0           0

Misses in library cache during parse: 10000

10003  user  SQL statements in session.

0  internal SQL statements in session.

10003  SQL statements in session.

********************************************************************************

Trace file: zlm11g_ora_14341_ZLM01.trc

Trace file compatibility: 11.1.0.7

Sort options: default

1  session in tracefile.

10003  user  SQL statements in trace file.

0  internal SQL statements in trace file.

10003  SQL statements in trace file.

10003  unique SQL statements in trace file.

90068  lines in trace file.

138  elapsed seconds in trace file.

分析:刚才的那段PL/SQL的语句被硬解析了10000次,并且执行了10000次,CPU总共消耗了6.26+0.23=6.50,花费时间6.53+0.26=6.79,可以看到,在trace文件中共有90068行,由于同样结构的SQL语句,未使用绑定变量,使Oracle认为每个语句都不同,因此产生了非常多的SQL语句,zlm01.log日志文件大小约为12M。

2.使用绑定变量的情况

--清空shared_pool

SQL> alter system flush shared_pool;

System altered.

--设置tracle文件标识符

SQL> alter session set tracefile_identifier=‘ZLM02‘;

Session altered.

--开启sql_trace

SQL> alter session set sql_trace=true;

Session altered.

--运行PL/SQL程序段

SQL> begin

2  for s in 1..10000

3  loop

4  execute immediate ‘select * from t1 where object_id=:s‘ using s;

5  end loop;

6  end;

7  /

PL/SQL procedure successfully completed.

--关闭sql_trace

SQL> alter session set sql_trace=false;

Session altered.

SQL> !

--再次查看用tkprof格式化以后的内容

[[email protected] trace]$ ll -lrth | grep ZLM02.trc

-rw-r----- 1 oracle oinstall  18K Sep 14 15:16 zlm11g_ora_14546_ZLM02.trc

[[email protected] trace]$ tkprof zlm11g_ora_14546_ZLM02.trc /home/oracle/zlm02.log

TKPROF: Release 11.2.0.3.0 - Development on Sun Sep 14 15:17:09 2014

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

[[email protected] trace]$

OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute  10015      0.13       0.11          0          0          0           0

Fetch       19      0.00       0.00          0         47          0          12

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total    10035      0.13       0.12          0         47          0          12

Misses in library cache during parse: 1

4  user  SQL statements in session.

12  internal SQL statements in session.

16  SQL statements in session.

********************************************************************************

Trace file: zlm11g_ora_14546_ZLM02.trc

Trace file compatibility: 11.1.0.7

Sort options: default

1  session in tracefile.

4  user  SQL statements in trace file.

12  internal SQL statements in trace file.

16  SQL statements in trace file.

16  unique SQL statements in trace file.

20156  lines in trace file.

118  elapsed seconds in trace file.

分析:使用绑定变量以后,前后对比一下,资源消耗降低了非常多。运行了10000次的SQL语句,只解析了1次,执行次数虽然多了15次,但CPU时间为0.13,消耗时间为0.11,基本可以忽略不计,trace文件中只有20156行,内容非常较之前要低了非常多,zlm02.log文件仅19k大小。

SQL> select sql_id,sql_text,executions from v$sqlarea where sql_text like ‘%select * from t1 where object_id=%‘;

SQL_ID        SQL_TEXT                                           EXECUTIONS

------------- -------------------------------------------------- ----------

28gj7tsy13xq8 select * from t1 where object_id=:i                     10000 --采用绑定变量的select语句也被执行了10000次

总结:在OLTP等报表系统中,当我们的应用中如果执行结构非常类似的语句:如,select * from t1 where object_id=‘10‘,select * from t1 where object_id=‘100‘,……如果不加绑定变量,会大大增加硬解析的次数,10000次执行,就有10000次硬解析(第一次执行时),如果再次执行,可能会因为在shared_pool缓存中已经存在,会有一部分软解析,而使硬解析数减少,而一旦使用了绑定变量,就算把shared_pool清空掉,也只需很少的几次硬解析,就可以执行10000次查询语句,大大减少了SGA中对shared_pool的占用,提高查询性能。如果在OLAP中,使用绑定变量需要谨慎,未必一定会提高性能,具体情况还需具体分析,这种情况仅仅适合OLTP系统。

时间: 2024-11-09 00:47:12

通过绑定变量优化OLTP系统性能的相关文章

SQL 绑定变量优化

这个方案要点在于以下三点: 1,  每次拼接条件时,都把条件对应的变量值塞入嵌套表中.因为是一一对应的,因此在取变量值时,很容易就匹配上. 2,  因为绑定变量执行时,using一定要把所有的绑定变量值都列出来.因此最后,最后会有一个case语句,根据变量个数来确定执行那个分支. 3,  嵌套表的类型是字符类型的.因此要获取日期类型和数字类型值时,记得加上to_date 和to_number转换. 如果对用例有疑问,可是随时找我沟通.同时也请汪文娟同学督促各开发分组接口人向分组内宣导,以后新上线

Oracle 学习之性能优化(三)绑定变量

根据Oracle 学习之性能优化(二)游标中的描述,我们知道如下两条语句是不共享的. select * from emp where empno=7698; select * from emp where empno=7566; 这样就造成每次执行用户的查询都要进行硬解析,但是我们知道,其他这两个语句的执行计划应该是相同.那么有什么方法能避免不必要的硬解析吗?这里我们提供2种方法. 一.绑定变量 SQL> variable empno number; SQL> exec :empno := 7

PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量

2014-09-25 BaoXinjian 一.绑定变量用法和使用场合 使用绑定变量的重要性:如果不使用绑定变量而使用常量,会导致大量硬解析.由于硬解析的种种危害,不使用绑定变量往往是影响oracle性能和扩展性的最大问题 以下为一些错误写法和正确写法的例子 1. PLSQL中普通查询 (1). 错误写法 SELECT * FROM emp WHERE empno=123; (2). 正确写法(未使用绑定变量) Empno:=123;SEELCT* FROM emp WHERE empno=:e

Oracle绑定变量窥探

随着具体输入值的不同,SQL的where条件的可选择率(Selectivity)和结果集的行数(Cardinality)可能会随之发生变化,而Selectivity和Cardinality的值会直接影响CBO对于相关执行步骤成本值的估算,进而影响CBO对SQL执行计划的选择.这就意味着随着具体输入值的不同,目标SQL执行计划可能会发生变化. 对于不使用绑定变量的SQL而言,具体输入值一量发生了变化,目标SQL的SQL文本就会随之发生变化,这样Oracle就能很容易地计算出对应Selectivit

oracle中关于替代变量,accpt,绑定变量,字符变量

此文档介绍两个事情,一个是替代变量,另一个就是了解一下硬解析和软解析对于变量来说declare定义的好还是variable定义的好 在oracle 中,对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析,一种叫做软解析.一个硬解析需要经解析,制定执行路径,优化访问计划等许多的步骤.硬解释不仅仅耗费大量的cpu,更重要的是会占据重要的们闩(latch)资源,严重的影响系统的规模的扩大(即限制了系统的并发行),而且引起的问题不能通过增加内存条和cpu的数量来解决.之所以这样是因为门闩

Oracle 数据库的绑定变量特性及应用

Oracle 数据库的绑定变量特性及应用[-----]转载自https://www.cnblogs.com/rootq/(原地址) 关键词: 绑定变量(binding variable),共享池(shared buffer pool), SGA(system global area); 在开发一个数据库系统前,有谁对Oracle 系统了解很多,尤其是它的特性,好象很少吧;对初学者来讲,这更是不可能的事情;仅仅简单掌握了SQL的写法,就开始了数据库的开发,其结果只能是开发一个没有效率,也没有可扩展

绑定变量窥测(Bind Variable Peeking)

绑定变量窥测是oracle在进行硬解析生成执行计划的时候会窥探绑定变量的真实值,去评估绑定变量的谓词条件的选择率,影响执行计划是选择访问路径是先走索引扫描进而去访问表还是直接走全表扫描. 没有绑定变量窥测这一特性的时候oracle怎么去评估选择性那,是基于字段统计信息中ndv,ndv接近表的行数的时候,选择性越高,走索引的概率越大,ndv越小,则选择性越差,走全表扫描的概率也就越大,但是在真实环境中,很多业务场景中字段取值都不均匀的,这个时候使用ndv去评估选择性显然不合理,所以绑定变量窥测会参

分页查询中绑定变量

在分页查询时,oracle绑定变量的使用优化 var a numbervar b numbervar c numberexec :a:=0exec :b:=10exec :c:=0set serveroutput off;alter session set statistics_level=all;SELECT * FROM (SELECT T1_.*, rownum ROWNUM_ FROM ( SELECT O.* FROM yyf.testa O WHERE 1=1 AND O.CREAT

【PLSQL】绑定变量,动态SQL,硬解析和软解析

************************************************************************   ****原文:blog.csdn.net/clark_xu 徐长亮的专栏 ************************************************************************ 1.1 变量 在匿名块或者存储过程中定义的变量为局部变量,及作用域在整个匿名块或存储过程中.运行结束,则该变量就不存在了: 绑定变