1. https://www.cnblogs.com/augus007/articles/9273236.html

一、游标

我们要先说一下游标这个概念。

从 Oracle 数据库管理员的角度上说,游标是对存储在库缓存中的可执行对象的统称。SQL 语句是存储在库缓存中的,它是游标。除了它之外,还有 Oracle 的存储过程也是存储在库缓存中的可执行对象,从 Oracle DBA 的角度上说,它也是游标。Oracle 也把它算为游标,在某些和游标相关的视图中,也会显示存储过程的一些信息的。但从开发者的角度说,只有 SQL 语句才是游标。

游标分为:open_cursors和session_cached_cursor 以及DICTIONARY LOOKUP CURSOR CACHED

参见:oracle参数open_cursors和session_cached_cursor详解!

二、关于游标的视图

你的应用程序或许是用 Java、Pro*C 等语言开发的,也可能有中件间,等等,对于 DBA 来说,我们不必过多的关心这些。以一个常见的三层应用为例, 如下图:

类似的图我们在很多地方都可以看到,假设这是一个三层 J2EE 应用。客户端调用的 Java 应用程序存放在中间的应用服务器层,应用程序的执行由应用服务器负责。

如上图这段 Java 应用程序,它的执行就是应用应用服务器的任务。但是,当执行到 executeQuery ("select * from Test") 语句时,这条 Java 语句要求从数据库服务器中查询表 Test。发下图:

这条语句的执行,是由数据库服务器负责的。数据库服务器只负责以最快的速度将 “Select * from test” 执行完毕。其他的它一概不负责。我们作为 DBA,只要保证 SQL 语句可以更快的执行就行了,至于应用程序逻辑方面的问题,不由我们负责。也就是说,作为 DBA,我们不必负责具体代码的问题,我们只负责 SQL 语句的执行。每条送交 Oracle 执行的 SQL 语句,无论这条语句是你手动在 SQL*Plus 命令窗口中敲入的,还是应用服务器传送给 Oracle 要求执行的,它们都以一样的方式被传递到 Oracle 中,由服务器进程执行。这些 SQL 语句的执行情况、具体的执行计划等数据资料会在一些视图中被记录下来,以供 DBA 追踪问题、调优 SQL 的执行。

下面,我们就介绍一下这些相关 SQL 执行情况的视图。我们再强调一个名词,对于从任何地方传递给 Oracle 数据库服务器要求执行的东西,我们都称为游标。它主要包括 SQL 语句和 PL/SQL 程序段。

1. V$SQL

  1. SQL_TEXTSQL 语句的文本
  2.  
  3. SQL_FULLTEXTSQL 语句的完全文本
  4.  
  5. SQL_ID

SHARABLE_MEM:游标所占共享内存

  1. PERSISTENT_MEM:游标持续期所占用的 Fixed(固定)内存
  2.  
  3. RUNTIME_MEM:游标在运行期所占用的 Fixed(固定)内存

SORTS:游标完成的排序次数

  1. LOADED_VERSIONS:游标在库缓存所占的内存堆是否被加载
  2.  
  3. OPEN_VERSIONS:游标是否被锁定。
  4.  
  5. USERS_OPENING:打开游标的会话数。也就是当正在缓存游标到 PGA 中的会话数。游标被执行三次后,就会被缓存到 PGA 中。此数值就加 1

FETCHES:抓取的次数

EXECUTIONS:执行次数

  1. PX_SERVERS_EXECUTIONS:以并行方式执行的总次数
  2.  
  3. END_OF_FETCH_COUNT:抓取全部行的次数
  4.  
  5. USERS_EXECUTING:当前正在执行此游标的会话数

LOADS:游标被加载或重新加载到库缓存中的次数。游标只所以被重新加载有可能是游标无效或库缓存内存不足。

  1. FIRST_LOAD_TIME:游标被第一次被加载的时间。也就是生成执行计划的时间

INVALIDATIONS:游标的无效次数

PARSE_CALLS:游标的解析次数,包括硬解析与软解析

DISK_READS:游标执行了多少次物理读

  1. DIRECT_WRITES:游标直接写的次数

BUFFER_GETS:逻辑读的次数

  1. APPLICATION_WAIT_TIME:应用程序的等待时间,单位微秒
  2.  
  3. CONCURRENCY_WAIT_TIME:并行的等待时间,单位微秒
  4.  
  5. CLUSTER_WAIT_TIMECluster 等待时间

USER_IO_WAIT_TIME:用户 I/O 等待时间

  1. PLSQL_EXEC_TIMEPL/SQL 执行时间
  2.  
  3. JAVA_EXEC_TIMEJava 执行时间
  4.  
  5. ROWS_PROCESSED:游标一共抓取了多少行。同样的行,每抓取一次此列都会增加
  6.  
  7. COMMAND_TYPE:命令类型
  8.  
  9. OPTIMIZER_MODE:优化器模式
  10.  
  11. OPTIMIZER_COST:执行计划的成本
  12.  
  13. OPTIMIZER_ENV:执行时的环境
  14.  
  15. OPTIMIZER_ENV_HASH_VALUE:环境的 HASH
  16.  
  17. PARSING_USER_ID:最先解析此游标的用户的 ID
  18.  
  19. PARSING_SCHEMA_ID:最先解析此游标的方案 ID

PARSING_SCHEMA_NAME:最先解析此游标的方案 ID

  1. KEPT_VERSIONS:是否使用 DBMS_SHARED_POOL 包将游标 Pin 到库缓存中
  2.  
  3. ADDRESS:父游标句柄的地址
  4.  
  5. TYPE_CHK_HEAP
  6.  
  7. HASH_VALUE:游标的 HASH
  8.  
  9. OLD_HASH_VALUE:老 HASH
  10.  
  11. PLAN_HASH_VALUE:执行计划的 HASH 值。(上述三个 HASH 值并不相同)
  12.  
  13. CHILD_NUMBER:子游标数量
  14.  
  15. SERVICE
  16.  
  17. SERVICE_HASH
  18.  
  19. MODULE:第一次解析游标的应用程序名。可以在应用程序中通过调用DBMS_APPLICATION_INFO.SET_MODULE 设置。
  20.  
  21. MODULE_HASH:应用程序名的 HASH
  22.  
  23. ACTION:第一次解析时的动作名。可以在应用程序中通过调用 DBMS_APPLICATION_INFO.SET_ACTION 设置。
  24.  
  25. ACTION_HASH:动作名的 HASh
  26.  
  27. SERIALIZABLE_ABORTS:每个游标产生 ORA-08177 errors 错误(事务串行化无效)的次数。
  28.  
  29. OUTLINE_CATEGORY:大纲类型

CPU_TIME:游标解析、执行、抓取时所用的 CPU 时间。单位是微秒。

 

ELAPSED_TIME:游标解析、执行、抓取时所用的总时间。单位是微秒。

  1. OUTLINE_SID:大纲会话的 SID
  2.  
  3. CHILD_ADDRESS:游标本身的地址
  4.  
  5. SQLTYPE:游标所用的 SQL 语言的版本
  6.  
  7. REMOTE:游标是否是远端映像的
  8.  
  9. OBJECT_STATUS:对象状态
  10.  
  11. LITERAL_HASH_VALUE:游标文本的 HASH
  12.  
  13. LAST_LOAD_TIME:执行计划最后一次被加载到库缓存中的时间。
  14.  
  15. IS_OBSOLETE:当子游标太多时,此子游标是否被荒废。
  16.  
  17. CHILD_LATCH:保护游标的子闩编号
  18.  
  19. SQL_PROFILESQL 的概要文件
  20.  
  21. PROGRAM_ID:过程 ID
  22.  
  23. PROGRAM_LINE#
  24.  
  25. EXACT_MATCHING_SIGNATURE
  26.  
  27. FORCE_MATCHING_SIGNATURE
  28.  
  29. LAST_ACTIVE_TIME:最后一次使用执行计划的时间。
  30.  
  31. BIND_DATA:绑定变量的信息

这个视图中 DISK_READS、BUFFER_GETS、CPU_TIME、ELAPSED_TIME 这四个列在调优 SQL 语句时最为重要。在数据库系统的速度不是太另人满意时,如果你已经确定过了,不是其他方面的原因,而是 SQL 语句性能的问题,只是无法确定是那条、或那些条语句拖慢了整体的速度。那么此时选择调优物理读、逻辑读最多的,或最耗 CPU 时间的 SQL 语句进行调节,往往可以取得今人满意的性能增长。

我们也可以以 EXECUTIONS(执行次数)最多的 SQL 语句为调优对象。另外,PARSE_CALLS 是解析次数,对于此列值最多的 SQL 语句,我们可以看看是否可以降低语句的解析次数。

关于 SQL 调优,和程序的调优是一样的。如果我们从事过代码优化这样的工作,就会知道,对于一个大型的应用程序来说调优的方法也是要从执行次数最多的那部分代码、或从最消耗资源的代码入手。

还有一个问题,就是文档中关于这个视图会经常提到一个概念:子游标与父游标。如果两个游标的文本一模一样,但由于环境不同,比如,游标所操作的表是不同用户下的同名表,这两个游标是不能共享执行计划的。它们都有各自的执行计划存在库缓存中。这两个游标就是子游标,Oracle 还会建立一个父游标,父游标中没有执行计划,它只是文本相同但执行计划不同的所有游标的代表。

其实在库缓存中,即使没有文本相同的子游标,Oracle 会为每个游标都创建父游标。因为父游标是文本相同的子游标的代表吗,所有文本相同的游标共享同一个父游标。

也就是说,只要你执行 SQL 语句,Oracle 都会在库缓存中保存一父一子两个游标。如果你执行了文本相同但环境不同因而不能共享执行计划的 SQL 语句,那么一个父游标可能就对应多个子游标。

父游标没有执行计划,它只有一信息管理性数据,Oracle 添加它的目的就是为了管理文本相同的游标。有一个视图是专门针对父游标的,就是 V$sqlarea。下面我们说一下这个视图。

2. V$SQLAREA

V$SQLAREA 和 V$SQL 的列几乎是一模一样的。在 V$SQLAREA 中汇总了子游标的数据。如果有两个语句:语句 A 和语句 B,它们文本一模一样,但是由于环境不同没有共享执行计划,而是有各自的执行计划。也就是语句 A 和语句 B 是同一父游标下的子游标。在 V$SQL 视图中,因为它是显示子游标的,所以语句 A 和语句 B 各占一行,假设语句 A 的 DISK_READS(物理读)是 100,语句 B 的物理读是 3000。V$SQLAREA 是显示父游标信息的,语句 A 和语句 B 因为文本相同,它们两个对应同一个父游标,在 V$SQLAREA 中占一行。在 V$SQLAREA 中,语句 A 和语句 B 父游标行中的 DISK_READS 就是 3100,也就是语句 A 和语句 B 的和。V$SQLAREA 中的其它列也是如此,都是 V$SQL 中相应子游标的合计。

有一个列是 V$SQL 中没有的,就是:VERSION_COUNT,它是对应同一父游标的子游标的数量。如果这个数字太高,可能代表由于某些原因使本可以共享执行计划的游标没有共享。

3.V$open_cursor 与 Open_cursor 参数

这个视图和参数涉及游标的打开。什么是游标的打开,就是在库缓存中,用户在软、硬解析游标时,会在游标对象的句柄上加一个锁,也就是 Library cache lock。在解析并执行完游标后,这个锁并不会马上去掉,而是会一直保留着,直到用户发出了 Close 命令关闭游标时为止。我们在 SQL*Plus 命令窗口中发出的命令,在抓取完所有行后,SQL*Plus 将自动为我们发出 Close 命令来关闭游标。

当游标打开时,Library cache lock 将一直保持,这样,即使库缓存内存紧张,需要老化对象,也不会老化这些还正在加锁的对象。因此,如果用户不停的要求数据库服务器打开游标、执行 SQL,但却忘了关闭游标,这很容易耗尽共享池的内存。为此,Oracle 准备了一个参数,就是 Open_cursor,它的默认值在 9i 下是 50,在 10g 中是 300,也就是说,在 10g 下,每个会话最多只能同时打开 300 个游标。有了这个限制,就不用害怕用户不停的打开游标但又不关闭它,而耗尽共享池内存了。

如果会话同时打开的游标数量超出了 Open_cursor 参数的限制,Oracle 将禁止会话打开新的游标。同时报出错误:ORA-01000: 超出打开游标的最大数 。

在用户断开会话的连接后,会话打开的这些游标将自动关闭。

V$open_cursor 视图专用来查看当前会话打开的游标信息。它只能查看当前会话打开的游标。

4.CURSOR_SHARING 参数

如果应用程序中有很多类似下面这样的 SQL 语句:

select * from 某表 where id=1;

select * from 某表 where id=2;

select * from 某表 where id=50;

等等,这些 SQL 语句严格来说是无法共享游标(也就是共享执行计划)的,但是这些语句所需要执行计划其实都是一样的。无论你在表中查询 ID 为 1 的行还是查询 ID 为 100 的行,执行方式应该是一样的。如果你想让这样的语句共享游标,那么,你可以改变 Cursor_sharing 参数的值。

此参有三个值:

  • Ÿ EXACT:这个值是默认值。除非游标文本一模一样,否则不会共享游标。

  • Ÿ SIMILAR:这个最智能,如果游标只有条件中的数据值部分不同,并且库缓存中原有游标的执行计划对于新执行的 SQL 语句也是最优的,将不再为 SQL 语句创建新的游标,而是让它共享库缓存中原有的游标。

  • Ÿ FORCE :不比较执行计划是否最优,只要游标中除了条件中的数据值部分不同外,其他部分都相同,就会共享游标。

此参数可以在会话级修改,也就是可以使用 Alter session 修改它的值,这将只影响某一个会话,而不会影响其他会话。

[转帖]Oracle 性能优化 之 游标及 SQL的更多相关文章

  1. 【转载】我眼中的Oracle性能优化

    我眼中的Oracle性能优化 大家对于一个业务系统的运行关心有如下几个方面:功能性.稳定性.效率.安全性.而一个系统的性能有包含了网络性能.应用性能.中间件性能.数据库性能等等. 今天从数据库性能的角 ...

  2. 降低磁盘IO使Oracle性能优化(转)

    文章转自:http://blog.chinaunix.net/uid-26813519-id-3207996.html 硬件方面虽然只占Oracle性能优化的一个方面(另一方面是软件),但是仍不可忽视 ...

  3. 我眼中的 Oracle 性能优化

    恒生技术之眼 作者 林景忠 大家对于一个业务系统的运行关心有如下几个方面:功能性.稳定性.效率.安全性.而一个系统的性能有包含了网络性能.应用性能.中间件性能.数据库性能等等. 今天从数据库性能的角度 ...

  4. oracle性能优化之awr分析

    oracle性能优化之awr分析 作者:bingjava 最近某证券公司系统在业务期间系统运行缓慢,初步排查怀疑是数据库存在性能问题,因此导出了oracle的awr报告进行分析,在此进行记录. 导致系 ...

  5. Oracle性能优化1-总体思路和误区

    最近在看梁敬彬老师关于Oracle性能优化的一些案例,在这里做一些简单的总结 1.COUNT(*)与COUNT(列)哪个更快 drop table t purge; create table t as ...

  6. Oracle 性能优化的基本方法

    Oracle 性能优化的基本方法概述 1)设立合理的性能优化目标. 2)测量并记录当前性能. 3)确定当前Oracle性能瓶颈(Oracle等待什么.哪些SQL语句是该等待事件的成分). 4)把等待事 ...

  7. Oracle性能优化小结

    Oracle性能优化小结 原则一.注意where子句中的连接顺序 Oracle采用自下而上的顺序解析where子句,根据这个原理,表之间的连接必须卸载其他where条件之前,哪些可以滤掉最大数量记录的 ...

  8. oracle 性能优化建议小结

    原则一:注意WHERE子句中的连接顺序: ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHER ...

  9. 浅谈Oracle 性能优化

    基于大型Oracle数据库应用开发已有6个年头了,经历了从最初零数据演变到目前上亿级的数据存储.在这个经历中,遇到各种各样的性能问题及各种性能优化. 在这里主要给大家分享一下数据库性能优化的一些方法和 ...

  10. Oracle性能优化之查询语句通用原则

    作者早期文章 Oracle优化 索引是表的一个概念部分 , 用来提高检索数据的效率, ORACLE 使用了一个复杂的自平衡 B-tree 结构 . 通常 , 通过索引查询数据比全表扫描要快 . 当 O ...

随机推荐

  1. poweroff详解

    linux下poweroff命令详解 reboot.halt.poweroff三条命令意思作用一样 阅读这三个命令的man帮助信息后,发现实现的是相同的功能. 作用: 重启或者关闭系统 语法: reb ...

  2. MyBatis 批量更新的处理

    一般来讲,在使用 MyBatis 进行数据库的访问时,通常会遇到需要更新数据的相关业务,在某些业务场景下,如果需要进行一批次的数据更新,可能性能不是特别理想.本文将简要介绍几种能够高效地处理批量更新数 ...

  3. Mysql在sql中截取时间类型字段的年月日和时间

    DATE_FORMAT() 函数 DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据. 下面的脚本使用 DATE_FORMAT() 函数来显示不同的格式.我们使用 NOW() 来获得当 ...

  4. Vue源码学习(十九):router基本原理

    好家伙,   0.什么是路由? 路由就是匹配到对应路径显示对应的组件! 那么我们要如何去实现? 我们来回忆一下这router怎么用的 1. 声明式路由配置:在路由配置对象中,定义路径与组件的映射关系. ...

  5. C#判断字符串是否是有效的XML格式数据

    说明 在try-catch语句块中,创建XmlDocument对象,并使用LoadXml方法加载xml字符串.如果没有异常,则说明xml字符串是有效的,返回true,反之为false. 代码实现 // ...

  6. 案例展示自定义C函数的实现过程

    摘要:用户在使用数据库过程中,受限于内置函数的功能,部分业务不易实现时,可以使用自定义C函数实现特殊功能.本文通过两个示例展示自定义C函数的实现过程. 前言 用户在使用数据库过程中,常常受限于内置函数 ...

  7. 云原生开发者须具备的1+N技能,开启第二曲线

    摘要:云的大环境下,意味以云为中心的快速应用开发能力将成为"胜负手".在现如今如此复杂的外部环境,且高速发展的情况下,为了不重蹈覆辙,必须需要开发者的第二曲线来破局! 随着云计算的 ...

  8. Python图像处理丨基于K-Means聚类的图像区域分割

    摘要:本篇文章主要讲解基于理论的图像分割方法,通过K-Means聚类算法实现图像分割或颜色分层处理. 本文分享自华为云社区<[Python图像处理] 十九.图像分割之基于K-Means聚类的区域 ...

  9. Git工作流中常见的三种分支策略:GitFlow、GitHubFlow和GitLabFlow

    摘要:聊一聊Git中的工作流--分支策略. 本文分享自华为云社区<Git工作流中常见的三种分支策略:GitFlow.GitHubFlow以及GitLabFlow>,原文作者:敏捷的小智. ...

  10. IOS上架流程详解,包含审核避坑指南!

    ​ 准备 开发者账号 完工的项目 上架步骤 一.创建App ID 二.创建证书请求文件 (CSR文件) 三.创建发布证书 (CER) 四.创建Provisioning Profiles配置文件 (PP ...