Oracle设计shared pool内存的一个主要目的就是语句共享,通过语句共享,节省语句的解析时间,从而得到性能的提升。如果解释shared pool内存,工作量太大,这里只是做一个非常简单的演示。
查看语句共享可以借助两个数据字典:V$SQLAREA和V$SQL
V$SQLAREA:保留SQL语句的父游标信息,可以通过SQL_ID标识,其中的VERSION_COUNT列表示子游标的数量
V$SQL :保留SQL语句的子游标信息,可以通过SQL_ID和CHILD_NUMBER标识
V$SQL_SHARED_CURSOR:语句产生子游标的原因
首先确认参数cursor_sharing,默认值是EXACT,也就是说只有在不使用绑定变量的情况下,语句要完全一样才可以共享,包括大小写、空格回车等所有都要一样。
SQL> conn / as sysdba
Connected.
SQL> show parameter cursor_sharing
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing string EXACT
清空shared_pool内存,这个命令可以在实验的时候使用,在生产系统库要谨慎
SQL> alter system flush shared_pool;
System altered.
在SCOTT用户下和TJ用户下有一模一样的表叫做demo,这是我准备的实验场景,以下操作,浅色表示第一个窗口或者session,深色表示在另外一个窗口或session查询动态性能视图信息验证
在第一个窗口:
SQL> conn scott/tiger
Connected.
SQL> select * from demo;
EMPNO ENAME SAL
---------- ---------- ----------
7369 SMITH 1200
7499 ALLEN 1600
7521 WARD 1250
7566 JONES 2975
SQL> select empno,ename from demo where empno=7369;
EMPNO ENAME
---------- ----------
7369 SMITH
由于上边这条语句是清空share pool后第一次执行,所以Oracle要做硬解析,生成游标,确切来讲是一个父游标和一个子游标,分别可以通过V$SQLAREA和V$SQL查到相关信息
在第二个窗口:
[oracle@asm11g workshop]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.3.0 Production on Sun Sep 16 21:20:24 2012
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, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options
SQL> get qs.sql
1 col sql_text for a50
2 set linesize 120
3 col exec for 999
4 col invalid for 99
5 col loads for 999
6 select sql_text,
7 sql_id,
8 hash_value,
9 executions exec,
10 loads,
11 invalidations invalid
12 from v$sqlarea
13* where sql_text like '&text%'
SQL> @qs
Enter value for text: select empno
old 9: where sql_text like '&text%'
new 9: where sql_text like 'select empno%'
SQL_TEXT SQL_ID HASH_VALUE EXEC LOADS INVALID
-------------------------------------------------- ------------- ---------- ---- ----- -------
select empno,ename from demo where empno=7369 dhdkpzyv9b1w7 3063252871 1 1 0
SQL> select sql_id,child_number,executions,loads from v$sql where sql_id='dhdkpzyv9b1w7';
SQL_ID CHILD_NUMBER EXECUTIONS LOADS
------------- ------------ ---------- -----
dhdkpzyv9b1w7 0 1 1
通过查询我们可以看到,V$SQLAREA数据字典中的是父游标的信息,语句解析(LOADS)了一次,执行(EXEC)了一次,当然在V$SQL中也可以看到类似的信息。
到第一个窗口:
SQL> select empno,ename from demo where empno=7369;
EMPNO ENAME
---------- ----------
7369 SMITH
再一次执行上一条语句,由于语句在share pool内存中已经有游标存在,所以语句会共享。
到第二个窗口:
SQL> @qs
Enter value for text: select empno
old 9: where sql_text like '&text%'
new 9: where sql_text like 'select empno%'
SQL_TEXT SQL_ID HASH_VALUE EXEC LOADS INVALID
-------------------------------------------------- ------------- ---------- ---- ----- -------
select empno,ename from demo where empno=7369 dhdkpzyv9b1w7 3063252871 2 1 0
SQL> select sql_id,child_number,executions,loads from v$sql where sql_id='dhdkpzyv9b1w7';
SQL_ID CHILD_NUMBER EXECUTIONS LOADS
------------- ------------ ---------- -----
dhdkpzyv9b1w7 0 2 1
通过上面的查询我们可以看到,语句解析(LOADS)了一次,执行(EXEC)了两次,在子游标也可以看到相同的信息。
到第一个窗口:
SQL> select empno,ename from demo where empno=7499;
EMPNO ENAME
---------- ----------
7499 ALLEN
这个语句和刚刚的语句的区别在于我把条件改成了7499,这样这就是一个全新的语句,Oracle要做硬解析,并在内存中申请新的父子游标。
第二个窗口:
SQL> @qs
Enter value for text: select empno
old 9: where sql_text like '&text%'
new 9: where sql_text like 'select empno%'
SQL_TEXT SQL_ID HASH_VALUE EXEC LOADS INVALID
-------------------------------------------------- ------------- ---------- ---- ----- -------
select empno,ename from demo where empno=7499 0m3wzw5mrdg8z 1735834911 1 1 0
select empno,ename from demo where empno=7369 dhdkpzyv9b1w7 3063252871 2 1 0
到第一个窗口:
切换用户到tj,tj用户下也有相同的表demo,执行select empno,ename from demo where empno=7369;
SQL> conn tj/tj
Connected.
SQL> select empno,ename from demo where empno=7369;
EMPNO ENAME
---------- ----------
7369 SMITH
到第二个窗口:
SQL> @qs
Enter value for text: select empno
old 9: where sql_text like '&text%'
new 9: where sql_text like 'select empno%'
SQL_TEXT SQL_ID HASH_VALUE EXEC LOADS INVALID
-------------------------------------------------- ------------- ---------- ---- ----- -------
select empno,ename from demo where empno=7499 0m3wzw5mrdg8z 1735834911 1 1 0
select empno,ename from demo where empno=7369 dhdkpzyv9b1w7 3063252871 3 2 0
SQL> select sql_id,child_number,executions,loads from v$sql where sql_id='dhdkpzyv9b1w7';
SQL_ID CHILD_NUMBER EXECUTIONS LOADS
------------- ------------ ---------- -----
dhdkpzyv9b1w7 0 2 1
dhdkpzyv9b1w7 1 1 1
虽然tj用户下的语句和scott用户下写的语句一模一样,但是语意显然不一样,两个demo表属于不同的用户,所以我们看到,Oracle的父游标解析(LOADS)加1,执行次数也加1,从父游标的角度来讲,语句是共享的,而在子游标中,有了区别,新生成了一个子游标CHILD_NUMBER 为1,解析(LOADS)了一次,执行了一次。
到第一个窗口:
再次执行语句
SQL> select empno,ename from demo where empno=7369;
EMPNO ENAME
---------- ----------
7369 SMITH
到第二个窗口:
SQL> @qs
Enter value for text: select empno
old 9: where sql_text like '&text%'
new 9: where sql_text like 'select empno%'
SQL_TEXT SQL_ID HASH_VALUE EXEC LOADS INVALID
-------------------------------------------------- ------------- ---------- ---- ----- -------
select empno,ename from demo where empno=7499 0m3wzw5mrdg8z 1735834911 1 1 0
select empno,ename from demo where empno=7369 dhdkpzyv9b1w7 3063252871 4 2 0
SQL> select sql_id,child_number,executions,loads from v$sql where sql_id='dhdkpzyv9b1w7';
SQL_ID CHILD_NUMBER EXECUTIONS LOADS
------------- ------------ ---------- -----
dhdkpzyv9b1w7 0 2 1
dhdkpzyv9b1w7 1 2 1
我们看到语句的父游标解析次数没有增加,执行次数加1,而对于子游标来说,CHILD_NUMBER 为1的子游标执行次数加1。
产生子游标的原因很多,比如我上边的用户方案(SCHEMA)改变的例子,当然还有很多其他原因也可以导致子游标的产生,比如优化器模式的改变,或者绑定变量的窥视等,如果你想确定是由那种原因造成的,需要查看v$sql_shared_cursor
对于刚才的例子,属于验证/事物检查不匹配
SQL> select sql_id,CHILD_NUMBER,AUTH_CHECK_MISMATCH from v$sql_shared_cursor where sql_id='dhdkpzyv9b1w7';
SQL_ID CHILD_NUMBER A
------------- ------------ -
dhdkpzyv9b1w7 0 N
dhdkpzyv9b1w7 1 Y
分享到:
相关推荐
在"游标.txt"文件中,可能包含了更多关于Oracle游标的使用实例和技巧,包括游标的声明、动态游标、游标变量、游标表达式以及游标在存储过程和函数中的应用。这些内容可以帮助你更深入地理解和掌握Oracle游标,提高你...
Oracle游标是数据库编程中非常重要的一个概念,主要用于处理SQL查询的结果集。游标允许我们按行处理数据,逐条读取结果集,而不仅仅是一次性获取所有数据。在Oracle数据库中,游标对于复杂的事务处理、动态SQL以及...
Oracle游标是数据库编程中非常重要的一个概念,它允许开发者逐行处理查询结果集,而不仅仅是一次性处理所有数据。在Oracle中,游标分为隐式游标和显式游标。 **一、游标简介** 游标的核心功能是提供一种方式来遍历...
### Oracle游标使用详解 #### 一、Oracle游标简介 在Oracle数据库中,游标是一种重要的机制,用于处理查询结果集。它允许用户通过PL/SQL编程语言逐行访问和处理查询返回的数据记录。游标可以是显式定义的(即在...
总之,Oracle游标提供了处理查询结果的强大工具,使开发者能够灵活地在PL/SQL中操作数据。无论是隐式还是显式游标,都极大地增强了对数据库的交互能力,使得程序能根据查询结果进行适当的操作。理解并熟练运用游标是...
Oracle 游标 FOR 循环 Oracle 游标 FOR 循环是 Oracle 数据库中的一种编程技术,用于实现游标的循环操作。游标 FOR 循环可以代替传统的游标循环,具有简洁易用的优点。 游标 FOR 循环的优点 游标 FOR 循环的优点...
Oracle 游标使用方法及语法大全 Oracle 游标是 PL/SQL 程序中...Oracle 游标是一种强大的工具,用于处理查询结果集,可以用于查询、更新和删除数据行。但是,需要注意游标的使用方法和语法,以免出现错误或锁定问题。
通过本篇Oracle游标的使用大全,我们可以了解到Oracle数据库游标的类型、属性以及如何在PL/SQL中实现对数据集的逐行处理。这不仅有助于提升程序员的编程技能,也能使他们更深入地理解PL/SQL与Oracle数据库之间的交互...
以上只是对Oracle游标使用的一个简要概述,具体到《Oracle 游标使用大全》这份文档,可能会包含更详尽的示例、技巧和案例,帮助开发者更好地理解和运用Oracle游标。通过学习和实践,我们可以提升数据库操作的效率和...
根据提供的标题、描述以及部分代码内容,我们可以详细探讨Oracle游标的使用方法,特别是明确游标(Explicit Cursor)和隐式游标(Implicit Cursor)的区别及其具体应用方式。 ### Oracle游标简介 在Oracle数据库中...
### Oracle游标使用及实例详解 #### 一、Oracle游标概述 在Oracle数据库中,游标(Cursor)是一种用于处理SQL查询结果集的方式。它允许用户逐行地读取和处理查询结果,这对于需要对每一行数据进行特定操作的情况非常...
### Oracle游标使用详解 #### 一、游标概述 游标是Oracle数据库中用于处理查询结果集的强大工具,尤其适用于需要逐行处理查询结果的情况。在Oracle中,游标可以分为两类:**显式游标**和**隐式游标**。 1. **隐式...
通过这些知识点的学习,读者可以更好地理解和应用Oracle游标,提高开发效率和代码质量。此外,还探讨了游标属性的应用场景以及如何通过循环来遍历游标,这对于处理大量数据尤其有用。总之,熟练掌握Oracle游标的使用...
Oracle游标是数据库编程中非常重要的一个概念,主要用于处理SQL查询的结果集。游标允许我们按需逐行处理数据,而不是一次性加载所有结果。这里详细介绍了Oracle中的三种游标类型:隐式游标、显式游标和REF游标。 1....
Oracle游标是数据库管理系统中的一种重要机制,它允许程序员逐行处理查询结果集,而不仅仅是一次性获取所有数据。游标类似于C语言中的指针,能够灵活、高效地处理多条记录,尤其在需要循环处理或者根据当前行数据做...
#### Oracle游标的基本概念 1. **定义**:在Oracle中,游标是一种服务器端的工作区,用来保存SELECT语句的结果集。当执行一个查询时,如果结果集很大,将其全部加载到内存中可能会非常低效甚至不可能。因此,Oracle...
在本文中,我们将对 Oracle 游标的使用进行详细的介绍,包括游标的基本概念、游标的类型、游标的使用、游标的属性等方面。 一、游标的基本概念 游标(Cursor)是 PL/SQL 中的一种数据访问机制,通过游标,可以访问...
综上所述,Oracle游标及其相关概念是PL/SQL编程中不可或缺的一部分,它们为数据处理提供了强大的工具和灵活性。正确理解和运用游标、%TYPE属性、DML语句以及事务控制等概念,对于高效开发和维护Oracle数据库应用程序...
Oracle数据库中的游标是PL/...总之,Oracle游标提供了一种灵活的方式来处理SQL查询的结果,允许程序逐行操作数据,这在处理复杂业务逻辑和事务时尤为有用。理解并熟练掌握游标的使用,能够提高数据库应用的效率和性能。