热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

【cursor_sharing】cursor_sharing参数设置exact,similar,force的区别

Oracle中为了提高sql的执行效率,需要减少硬解析,实现sharedcursor共享,最常见的方法是使用绑定变量,但很多时候由于各种原因

Oracle中为了提高sql的执行效率,需要减少硬解析,实现shared cursor共享,最常见的方法是使用绑定变量,但很多时候由于各种原因

Oracle中为了提高sql的执行效率,需要减少硬解析,实现shared cursor共享,最常见的方法是使用绑定变量,但很多时候由于各种原因未能在开发初期使用绑定变量,对于减少硬解析的目的,退而求其次地方法是设置cursor_sharing.

1.准备环境

实验环境

BALLON@PROD> select * from v$version;

BANNER

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

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE 10.2.0.1.0 Production

TNS for Linux: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 – Production

使用脚本插入数据后:

BALLONTT@PROD> desc t;

Name Null? Type

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

ID VARCHAR2(5)

NAME NUMBER(38)

BALLONTT@PROD> select id,count(*) from t group by id;

ID COUNT(*)

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

d 6

a 10000

b 20000

c 20

BALLONTT@PROD> create index ind_id on t(id);

Index created.

2.取值为exact时(默认):

BALLONTT@PROD> show parameter cursor_sharing;

NAME TYPE VALUE

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

cursor_sharing string EXACT

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

20000

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

6

BALLONTT@PROD> select sql_text,sql_id,version_count,executions from v$sqlarea

where sql_text like 'select count(*) from t where id=%';

SQL_TEXT SQL_ID VERSION_COUNT EXECUTIONS

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

select count(*) from t where b0gfs7u9r55rv 1 1

select count(*) from t where fqurbumy7bsg6 1 1

可以看到两条查询语句没有使用绑定变量,有各自对应的sql_id,子游标数均为1个。两个sql查询没有任何关系。

查看两次sql的执行计划:

BALLONTT@PROD>select * from table(dbms_xplan.

display_cursor('b0gfs7u9r55rv',0,'advanced'));

PLAN_TABLE_OUTPUT

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

SQL_ID b0gfs7u9r55rv, child number 0

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

select count(*) from t where

Plan hash value: 3666266488

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | | | 1 (100)| |

| 1 | SORT AGGREGATE | | 1 | 2 | | |

PLAN_TABLE_OUTPUT

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

|* 2 | INDEX RANGE SCAN| IND_ID | 14 | 28 | 1 (0)| 00:00:01 |

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

第一次查询利用了索引。

BALLONTT@PROD> select * from table(dbms_xplan.display_cursor('fqurbumy7bsg6',0,'advanced'));

PLAN_TABLE_OUTPUT

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

SQL_ID fqurbumy7bsg6, child number 0

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

select count(*) from t where

Plan hash value: 2966233522

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | | | 15 (100)| |

| 1 | SORT AGGREGATE | | 1 | 2 | | |

PLAN_TABLE_OUTPUT

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

|* 2 | TABLE ACCESS FULL| T | 19783 | 39566 | 15 (0)| 00:00:01 |

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

第二次查询利用了全表扫描

我们在更直观地来看一下两次sql查询后的硬解析统计情况:

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

10000

BALLONTT@PROD> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

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

parse time cpu 2133

parse time elapsed 4463

parse count (total) 54889

parse count (hard) 6579(硬解析数目)

parse count (failures) 52

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

20

BALLONTT@PROD> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

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

parse time cpu 2134

parse time elapsed 4464

parse count (total) 54895

parse count (hard) 6580(硬解析数目)

parse count (failures) 52

硬解析数目再次加1

因为数据的巨大差异性,,导致了对两次查询有不同的执行计划,这也说明在cursor设置为exact时,两条sql语句如果存在一点不同,就不会共享cursor,而进行两次硬解析。

3.设置为force时

Oracle对输入的SQL值,会将where条件取值自动替为绑定变量。以后在输入相同的结构SQL语句时,会进行cursor sharing共享游标

BALLONTT@PROD> alter system set cursor_sharing=force;

System altered.

BALLONTT@PROD> show parameter cursor_sharing;

NAME TYPE VALUE

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

cursor_sharing string FORCE

清除一下share pool中已缓存的cursor

BALLONTT@PROD> alter system flush shared_pool;

System altered.

查看硬解析情况:

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

20000

BALLONTT@PROD> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

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

parse time cpu 2163

parse time elapsed 4506

parse count (total) 55097

parse count (hard) 6668

parse count (failures) 52

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

6

BALLONTT@PROD> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

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

parse time cpu 2164

parse time elapsed 4507

parse count (total) 55101

parse count (hard) 6669

parse count (failures) 52

硬解析加1了,这不应该呀!!

BALLONTT@PROD> select sql_text,child_number from v$sql where sql_text like 'select count(*) from t where id%';

SQL_TEXT CHILD_NUMBER

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

select count(*) from t where 0

select count(*) from t where 0

可以看到并没有使用绑定变量,force的设置没有生效。

解决办法:应在设置cursor_sharing前,执行两次下面语句:

alter system flush shared_pool;

BALLONTT@PROD> alter system flush shared_pool;

System altered.

BALLONTT@PROD> alter system flush shared_pool;

System altered.

BALLONTT@PROD> alter system set cursor_sharing=force;

System altered.

设置好了,接着进行sql测试

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

6

BALLONTT@PROD> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

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

parse time cpu 2216

parse time elapsed 4572

parse count (total) 55867

parse count (hard) 6910

parse count (failures) 55

BALLONTT@PROD> select count(*) from t where;

COUNT(*)

----------

20000

BALLONTT@PROD> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

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

parse time cpu 2216

parse time elapsed 4572

parse count (total) 55869

parse count (hard) 6910

parse count (failures) 55

硬解析的次数没有发生变化

BALLONTT@PROD> select sql_text,sql_id,version_count,executions from v$sqlarea

2 where sql_text like 'select count(*) from t where%';

SQL_TEXT SQL_ID VERSION_COUN EXECUTIONS

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

select count(*) from t where id=:"SYS_B_0" g82ztj8p3q174 1 2

可以看到两次查询使用了绑定变量,将谓词的值用sys_B_0代替。该语句执行了两次,有一个child cursor(子游标)。

在来看一下两次查询语句的执行计划:

BALLONTT@PROD> select * from table(dbms_xplan.display_cursor('g82ztj8p3q174',0,'advanced'));

PLAN_TABLE_OUTPUT

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

SQL_ID g82ztj8p3q174, child number 0

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

select count(*) from t where id=:"SYS_B_0"

Plan hash value: 3666266488

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | | | 1 (100)| |

| 1 | SORT AGGREGATE | | 1 | 4 | | |

PLAN_TABLE_OUTPUT

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

|* 2 | INDEX RANGE SCAN| IND_ID | 6 | 24 | 1 (0)| 00:00:01 |

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

两次的查询使用了同一个执行计划:索引扫描。这就是force的设置。

对与参数cusor_sharing设置为force时,根据实验,我们可以得出下列结论:


推荐阅读
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文主要讨论了在xps15上安装双系统win10和MacOS后,win10无法正常更新的问题。分析了可能的引导问题,并提供了解决方法。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 树莓派Linux基础(一):查看文件系统的命令行操作
    本文介绍了在树莓派上通过SSH服务使用命令行查看文件系统的操作,包括cd命令用于变更目录、pwd命令用于显示当前目录位置、ls命令用于显示文件和目录列表。详细讲解了这些命令的使用方法和注意事项。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
author-avatar
zj5415
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有