千家信息网

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

发表于:2024-10-02 作者:千家信息网编辑
千家信息网最后更新 2024年10月02日,根据Oracle 学习之性能优化(二)游标中的描述,我们知道如下两条语句是不共享的。select * from emp where empno=7698;select * from emp where
千家信息网最后更新 2024年10月02日Oracle 学习之性能优化(三)绑定变量

根据Oracle 学习之性能优化(二)游标中的描述,我们知道如下两条语句是不共享的。

select * from emp where empno=7698;select * from emp where empno=7566;

这样就造成每次执行用户的查询都要进行硬解析,但是我们知道,其他这两个语句的执行计划应该是相同。那么有什么方法能避免不必要的硬解析吗?这里我们提供2种方法。

一、绑定变量

SQL> variable empno number;SQL> exec :empno := 7839;PL/SQL procedure successfully completed.SQL> select ename from emp where empno = :empno;ENAME------------------------------KINGSQL>  exec :empno := 7782;PL/SQL procedure successfully completed.SQL> select ename from emp where empno = :empno;ENAME------------------------------CLARKSQL>

我们查看一下游标

SQL> COL SQL_TEXT FOR A30SQL> COL SQL_ID FOR A20SQL> SET LINESIZE 200SQL> SELECT sql_id,sql_text,executions,loads,version_count  FROM v$sqlarea WHERE sql_text LIKE '%:empno'; SQL_ID               SQL_TEXT                      EXECUTIONS          LOADS VERSION_COUNT-------------------- ------------------------------ ---------- ---------- -------------f6r0kqk0hsa7s        select ename from emp where em        2         1             1                     pno = :empnoSQL> SELECT sql_id,sql_text,loads,child_number,parse_calls  FROM v$sql WHERE sql_text LIKE '%:empno';SQL_ID               SQL_TEXT                           LOADS CHILD_NUMBER PARSE_CALLS-------------------- ------------------------------ ---------- ------------ -----------f6r0kqk0hsa7s        select ename from emp where em        1           0         2                     pno = :empnoSQL>

可见,父子游标都被共享啦。

在OLTP环境中,一定要使用绑定变量以避免系统有太多的硬解析。


我们验证一下,不使用绑定变量和使用了绑定变量后,性能到底有没有提升。

1. 建立一张表

SQL> create table t(id int,text varchar2(100));Table created.

2. 不使用绑定变量向表中插入10000行记录

SQL> set timing onSQL> declarebegin  for i in 1 .. 10000 loop     execute immediate 'insert into t values('||i||',''test bind variable'')';  end loop;  commit;end;/ PL/SQL procedure successfully completed.Elapsed: 00:00:06.43

系统产生了非常多的游标

SQL> set pause onSQL> SELECT sql_text,       sql_id,       EXECUTIONS,       LOADS,       VERSION_COUNT  FROM v$sqlarea WHERE sql_text LIKE 'insert into t%';   SQL_TEXT                       SQL_ID                    EXECUTIONS          LOADS VERSION_COUNT------------------------------ -------------------- ---------- ---------- -------------insert into t values(9156,'tes ah7vdgtnj80b1                     1         1             1t bind variable')insert into t values(8826,'tes 7yuz09vq9h0c4                     1         1             1t bind variable')insert into t values(9905,'tes 97c7m0gxj80cv                     1         1             1t bind variable')insert into t values(9396,'tes 9bvtw8y7080g5                     1         1             1t bind variable')SQL_TEXT                       SQL_ID                    EXECUTIONS          LOADS VERSION_COUNT------------------------------ -------------------- ---------- ---------- -------------insert into t values(9034,'tes ck51y8bu1c0jr                     1         1             1t bind variable')insert into t values(9153,'tes 7cxb26zpcn0q9                     1         1             1t bind variable')insert into t values(9783,'tes 7236x7yva40sq                     1         1             1t bind variable')insert into t values(9491,'tes cn2n05f70810f                     1         1             1


3. 使用绑定变量

SQL> set timing onSQL> declarebegin  for i in 1 .. 10000 loop     execute immediate 'insert into t values(:x,''test bind variable'')' using i;  end loop;  commit;end;/ PL/SQL procedure successfully completed.Elapsed: 00:00:00.43

使用绑定变量,执行速度快了很多倍。

SQL> SELECT sql_text,       sql_id,       EXECUTIONS,       LOADS,       VERSION_COUNT  FROM v$sqlarea WHERE sql_text LIKE 'insert into t%:x%'; SQL_TEXT                       SQL_ID                    EXECUTIONS          LOADS VERSION_COUNT------------------------------ -------------------- ---------- ---------- -------------insert into t values(:x,'test  0nhbks92x50kk            10000             1             1bind variable')

执行计划只有一个,被执行了10000次。


二、修改初始化参数

系统提供了一个初始化参数

SQL> show parameter cursor_sharingNAME                                 TYPE                             VALUE------------------------            -------------------               ------------------cursor_sharing                       string                           EXACT

CURSOR_SHARING determines what kind of SQL statements can share the same cursors.

Values:

  • FORCE
    Allows the creation of a new cursor if sharing an existing cursor, or if the cursor plan is not optimal.

  • SIMILAR
    Causes statements that may differ in some literals, but are otherwise identical, to share a cursor, unless the literals affect either the meaning of the statement or the degree to which the plan is optimized.

  • EXACT
    Only allows statements with identical text to share the same cursor

1. 清空shared_pool

SQL> set pagesize 10000SQL> set linesize 200SQL> col SQL_TEXT for a50SQL> col SQL_ID for 520SQL> col SQL_ID for a20SQL> alter system flush shared_pool;System altered.SQL> SELECT sql_text,       sql_id,       EXECUTIONS,       LOADS,       VERSION_COUNT  FROM v$sqlarea WHERE sql_text LIKE 'insert into t%';   2    3    4    5    6    7  no rows selectedSQL>

2. 将cursor_sharing改为FORCE,执行查询

SQL>  alter session set cursor_sharing=force;Session altered.Elapsed: 00:00:00.02SQL> declarebegin  for i in 1 .. 10000 loop     execute immediate 'insert into t values('||i||',''test bind variable'')';  end loop;  commit;end;/  2    3    4    5    6    7    8  PL/SQL procedure successfully completed.Elapsed: 00:00:01.15

3. 查看游标情况

SQL> SELECT sql_text,       sql_id,       EXECUTIONS,       LOADS,       VERSION_COUNT  FROM v$sqlarea WHERE sql_text LIKE 'insert into t%';no rows selectedSQL> /SQL_TEXT                                           SQL_ID                EXECUTIONS      LOADS VERSION_COUNT-------------------------------------------------- -------------------- ---------- ---------- -------------insert into t values(9966,'test bind variable')    07xgdm0uwn5gb            1     3                 1insert into t values(10000,'test bind variable')   76rf2hx2w45m1                 1     3                 1insert into t values(9969,'test bind variable')    bfayz4q1j4b37            1     3                 1insert into t values(9984,'test bind variable')    48t1dy0tahgxh            1     3                 1insert into t values(9998,'test bind variable')    04bhmfjq8hhtu            1     3                 1insert into t values(9967,'test bind variable')    0njsupf834kn0            1     3                 1insert into t values(9999,'test bind variable')    6uhdudx8k4rv3            1     3                 1insert into t values(9975,'test bind variable')    0tqj0jcamsspu            1     3                 1insert into t values(9957,'test bind variable')    a6as35h3wwu00            1     3                 1insert into t values(9970,'test bind variable')    58m581pqq8v4j            1     3                 1insert into t values(9982,'test bind variable')    3gh2q9f2wnxr8            1     3                 1insert into t values(9977,'test bind variable')    1t0t0jz9y0zg9            1     3                 1insert into t values(9988,'test bind variable')    111vappsrszy7            1     3                 1insert into t values(9994,'test bind variable')    8kvjy7tns10vq            1     3                 1insert into t values(9963,'test bind variable')    c1w951tadx4tb            1     3                 1insert into t values(9993,'test bind variable')    10h2mbxvtt9tm            1     3                 1insert into t values(9981,'test bind variable')    gv77ng7kndhty            1     3                 1insert into t values(9978,'test bind variable')    0v7773365tj70            1     3                 1insert into t values(9974,'test bind variable')    astu71gzn1uw5            1     3                 1insert into t values(9960,'test bind variable')    09d0bxcsndxzm            1     3                 1insert into t values(9959,'test bind variable')    7ht6qzyy0jz5w            1     3                 1insert into t values(9965,'test bind variable')    dgz4fbhzgpzh5            1     3                 1insert into t values(9989,'test bind variable')    3srf852y19zx6            1     3                 1insert into t values(9995,'test bind variable')    1r6tp423v613x            1     3                 1insert into t values(9976,'test bind variable')    9vxdayk3yq1nn            1     3                 1insert into t values(9958,'test bind variable')    9ptg2jd30k6d8            1     3                 1insert into t values(9968,'test bind variable')    akt2u5gn1y9kp            1     3                 1insert into t values(×××,'test bind variable')    ch5rx2b3ja9x8             1     3                 1insert into t values(9962,'test bind variable')    a2p68fsk6abwz            1     3                 1insert into t values(9997,'test bind variable')    f0474tah8ubzq            1     3                 1insert into t values(9972,'test bind variable')    gzqpvbrsn6ggk            1     3                 1insert into t values(9983,'test bind variable')    ah9r6ghzsugmp            1     3                 1insert into t values(9979,'test bind variable')    2cvqu9h5wagva            1     3                 1insert into t values(9996,'test bind variable')    3h90mc46sqmzr            1     3                 1insert into t values(9961,'test bind variable')    7t8njvfx8fn4y            1     3                 1insert into t values(9987,'test bind variable')    1qxhj0g7cuw8u            1     3                 1insert into t values(9991,'test bind variable')    5n2jahrk5z258            1     3                 1insert into t values(:"SYS_B_0",:"SYS_B_1")         950r47takm3c4       9953            1                 1insert into t values(9971,'test bind variable')    fyb5pvjuqz4d0            1     3                 1insert into t values(9955,'test bind variable')    1adu3pctt76bp            1     3                 1insert into t values(9990,'test bind variable')    62pp4zqc9r767            1     3                 1insert into t values(9973,'test bind variable')    adb60k3nxr9mk            1     3                 1insert into t values(9985,'test bind variable')    gz4hry47rzhvt            1     3                 1insert into t values(9986,'test bind variable')    b54fdtcu47v0d            1     3                 1insert into t values(9980,'test bind variable')    fvwh53nh7zvhk            1     3                 1insert into t values(9956,'test bind variable')    1vcjq6rm9gx72            1     3                 1insert into t values(9964,'test bind variable')    a06un7tf1rxgu            1     3                 1insert into t values(9954,'test bind variable')    0nb4synx6bxqv            1     3                 148 rows selected.SQL>

4. 再次清空shared_pool

SQL> alter system flush shared_pool;System altered.

5. 将cursor_sharing改为SIMILAR,执行查询

SQL> alter session set cursor_sharing=similar;Session altered.Elapsed: 00:00:00.03SQL> declarebegin  for i in 1 .. 10000 loop     execute immediate 'insert into t values('||i||',''test bind variable'')';  end loop;  commit;end;/  2    3    4    5    6    7    8  PL/SQL procedure successfully completed.Elapsed: 00:00:01.14

5. 查看共享游标

SQL> SELECT sql_text,       sql_id,       EXECUTIONS,       LOADS,       VERSION_COUNT  FROM v$sqlarea WHERE sql_text LIKE 'insert into t%';  2    3    4    5    6    7  SQL_TEXT                                           SQL_ID                EXECUTIONS      LOADS VERSION_COUNT-------------------------------------------------- -------------------- ---------- ---------- -------------insert into t values(9966,'test bind variable')    07xgdm0uwn5gb            1     4                 1insert into t values(10000,'test bind variable')   76rf2hx2w45m1                 1     4                 1insert into t values(9969,'test bind variable')    bfayz4q1j4b37            1     4                 1insert into t values(9984,'test bind variable')    48t1dy0tahgxh            1     4                 1insert into t values(9998,'test bind variable')    04bhmfjq8hhtu            1     4                 1insert into t values(9967,'test bind variable')    0njsupf834kn0            1     4                 1insert into t values(9999,'test bind variable')    6uhdudx8k4rv3            1     4                 1insert into t values(9975,'test bind variable')    0tqj0jcamsspu            1     4                 1insert into t values(9957,'test bind variable')    a6as35h3wwu00            1     4                 1insert into t values(9970,'test bind variable')    58m581pqq8v4j            1     4                 1insert into t values(9982,'test bind variable')    3gh2q9f2wnxr8            1     4                 1insert into t values(9977,'test bind variable')    1t0t0jz9y0zg9            1     4                 1insert into t values(9988,'test bind variable')    111vappsrszy7            1     4                 1insert into t values(9994,'test bind variable')    8kvjy7tns10vq            1     4                 1insert into t values(9963,'test bind variable')    c1w951tadx4tb            1     4                 1insert into t values(9993,'test bind variable')    10h2mbxvtt9tm            1     4                 1insert into t values(9981,'test bind variable')    gv77ng7kndhty            1     4                 1insert into t values(9978,'test bind variable')    0v7773365tj70            1     4                 1insert into t values(9974,'test bind variable')    astu71gzn1uw5            1     4                 1insert into t values(9960,'test bind variable')    09d0bxcsndxzm            1     4                 1insert into t values(9959,'test bind variable')    7ht6qzyy0jz5w            1     4                 1insert into t values(9965,'test bind variable')    dgz4fbhzgpzh5            1     4                 1insert into t values(9989,'test bind variable')    3srf852y19zx6            1     4                 1insert into t values(9995,'test bind variable')    1r6tp423v613x            1     4                 1insert into t values(9976,'test bind variable')    9vxdayk3yq1nn            1     4                 1insert into t values(9958,'test bind variable')    9ptg2jd30k6d8            1     4                 1insert into t values(9968,'test bind variable')    akt2u5gn1y9kp            1     4                 1insert into t values(×××,'test bind variable')    ch5rx2b3ja9x8             1     4                 1insert into t values(9962,'test bind variable')    a2p68fsk6abwz            1     4                 1insert into t values(9997,'test bind variable')    f0474tah8ubzq            1     4                 1insert into t values(9972,'test bind variable')    gzqpvbrsn6ggk            1     4                 1insert into t values(9983,'test bind variable')    ah9r6ghzsugmp            1     4                 1insert into t values(9979,'test bind variable')    2cvqu9h5wagva            1     4                 1insert into t values(9996,'test bind variable')    3h90mc46sqmzr            1     4                 1insert into t values(9961,'test bind variable')    7t8njvfx8fn4y            1     4                 1insert into t values(9987,'test bind variable')    1qxhj0g7cuw8u            1     4                 1insert into t values(9991,'test bind variable')    5n2jahrk5z258            1     4                 1insert into t values(:"SYS_B_0",:"SYS_B_1")         950r47takm3c4       9953            1                 1insert into t values(9971,'test bind variable')    fyb5pvjuqz4d0            1     4                 1insert into t values(9955,'test bind variable')    1adu3pctt76bp            1     4                 1insert into t values(9990,'test bind variable')    62pp4zqc9r767            1     4                 1insert into t values(9973,'test bind variable')    adb60k3nxr9mk            1     4                 1insert into t values(9985,'test bind variable')    gz4hry47rzhvt            1     4                 1insert into t values(9986,'test bind variable')    b54fdtcu47v0d            1     4                 1insert into t values(9980,'test bind variable')    fvwh53nh7zvhk            1     4                 1insert into t values(9956,'test bind variable')    1vcjq6rm9gx72            1     4                 1insert into t values(9964,'test bind variable')    a06un7tf1rxgu            1     4                 1insert into t values(9954,'test bind variable')    0nb4synx6bxqv            1     4                 148 rows selected.

和cursor_sharing=FORCE时,情况一样。


这两种方法都不推荐使用,有bug 。建议规范前台业务查询,尽量使用绑定变量。

变量 游标 查询 方法 系统 性能 参数 情况 语句 习之 相同 业务 业务查询 两个 再次 前台 只有 建议 父子 环境 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 河北什么是软件开发服务值得推荐 深圳云尖网络技术有限公司 山东迅虎网络技术有限责任公司 甘特图 软件开发计划 服务器读不到优盘需要设置什么 部队网络安全十条法则 硕士毕业论文查sci数据库嘛 网络安全ppt刘建伟 重装上阵服务器怎么看 茂名软件开发者在线咨询 网络安全问题的技术根源是 互联网科技最新排行榜 曙光服务器恢复raid 浪潮服务器怎么做raid 银航网络技术服务 中兴软件开发的发展前景 软件开发是什麽 中孚服务器管理 招标 安徽林飞互联网科技有限公司 戴尔服务器电源报警指示灯 石家庄龙腾软件开发公司 我的世界新建世界自动关闭服务器 2k21进去之后提示无法连接服务器 贫困生数据库对象 网络数据库安全措施有哪些 网络安全等级保护网网址 虹口区海航软件开发问答知识 8080抓服务器 六安中擎网络技术 甘肃人社认证服务器故障
0