- 浏览: 518913 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
u011165335:
distinct不影响使用半连接
(转)关于semi-join/anti-join的一点探讨 -
353790060:
redo 记录事务执行后的日志 undo 记录事务回滚的日志 ...
Oracle redo与undo浅析 -
jayxigua:
redo用于在失败时重放事务(即恢复事务),undo则用于取消 ...
Oracle redo与undo浅析 -
aa_qq110:
Openbravo有中文包吗
Openbravo开发手册 -
iocaop:
不错,写的很清晰易懂
JAVA 服务提供者框架介绍
oracle执行SQL语句就是打开游标,解析游标,执行游标,关闭游标的过程。了解游标的这几个阶段,我们也就弄清楚了SQL执行过程,这是本文要介绍的第一个内容。另外,在java编程中,我们通常说要使用预处理的形式来写SQL语句(比如:select * from table where A = ?),也就是绑定变量的形式。因为,这样效率高。那么,为什么使用绑定变量就比不使用绑定变量(比如:select * from table where A = '123')要效率高呢?这是本文要介绍的第二个内容。
一. 游标的生命周期
一条sql语句的执行过程,就是一个游标的生命周期。如下图所示:
1. 打开游标:系统为这个游标分配一个内存结构。
2. 解析游标:将一条SQL与这个游标关联。解析这条sql语句,将解析的结果加载到共享池中。
3. 定义输出变量:如果这条SQL返回数据,先定义接收数据的变量。
4. 定义输入变量:如果SQL语句使用了绑定变量,提供他们的值。
5. 执行游标:执行SQL语句。
6. 获取游标:如果SQL语句有返回数据,接收返回的数据。
7. 关闭游标:释放第一步分配的内存,供其他游标使用,但是第二步解析的SQL结果(也就是共享游标)不会被释放,以期待被重新使用。
我们可以通过一段PL/SQL代码来看一下游标的这几个步骤:
- DECLARE
- l_ename emp.ename%TYPE := 'SCOTT';
- l_empno emp.empno%TYPE;
- l_cursor INTEGER;
- l_retval INTEGER;
- BEGIN
- l_cursor := dbms_sql.open_cursor; /*打开游标*/
- dbms_sql.parse(l_cursor, 'SELECT empno FROM emp WHERE ename = :ename', 1); /*解析游标*/
- dbms_sql.define_column(l_cursor, 1, l_empno); /*定义输出变量*/
- dbms_sql.bind_variable(l_cursor, ':ename', l_ename); /*定义输入变量*/
- l_retval := dbms_sql.execute(l_cursor); /*执行游标*/
- IF dbms_sql.fetch_rows(l_cursor) > 0 /*获取游标*/
- THEN
- dbms_sql.column_value(l_cursor, 1, l_empno);
- dbms_output.put_line(l_empno);
- END IF;
- dbms_sql.close_cursor(l_cursor); /*关闭游标*/
- END;
二. 游标的解析过程
在游标的这几个过程中,我们唯一能影响的就是解析过程。解析过程的快与慢,与我们写的sql语句有直接关系。那么游标的解析过程(也就是SQL的解析过程)是怎样的呢?看下图:
1. 包含VPD的约束条件检查:如果系统中使用了虚拟私有数据库,并且被解析的SQL语句中引用的某张表激活了它的话,安全策略生成的约束条件会被添加到where条件中(说实话,这个我也没看懂,先不管)
2. 语法,语义以及访问权限检查:就是检查我们写的SQL写得对不对,引用的表是否存在等。
3. 将父游标保存到库缓存:如果没有找到共享的父游标,就会在库缓存中缓存这个父游标。父游标保存的是这条SQL的文本信息,今后如果重新执行这条SQL语句,这个父游标是可以重用的。
4. 逻辑优化与物理优化:生成这条SQL所有可能的执行计划,然后根据执行计划的开销,选择开销最小的一条执行计划。
5. 将子游标保存到库缓存:上一步选择的最优执行计划信息和当前的执行环境,会当做子游标的信息保存到库缓存,并与父游标关联。
总之,父游标保存的是SQL文本信息,今后可以被重用。子游标保存的是当前执行环境下所选择的这条SQL最优的执行计划,如果父游标被重用,执行环境没变,那么子游标也会被重用。
当父游标和子游标都可重用,那么只需要执行前2步,此时对应的解析称为软解析。如果父游标与子游标都不可重用,所有的步骤都执行的时候,就是我们说的硬解析。因为硬解析里面的逻辑优化与物理优化是非常依赖cpu的操作,所以硬解析相对而言是比较耗时的。也就是我们为什么说要尽可能避免硬解析。
三. 绑定变量优点
绑定变量可以有效消除硬解析,我们执行如下一段SQL文本:
- DROP TABLE t;
- CREATE TABLE t (n NUMBER, v VARCHAR2(4000));
- ALTER SYSTEM FLUSH SHARED_POOL;
- VARIABLE n NUMBER
- VARIABLE v VARCHAR2(32)
- EXECUTE :n := 1; :v := 'Helicon';
- INSERT INTO t (n, v) VALUES (:n, :v);
- EXECUTE :n := 2; :v := 'Trantor';
- INSERT INTO t (n, v) VALUES (:n, :v);
- EXECUTE :n := 3; :v := 'Kalgan';
- INSERT INTO t (n, v) VALUES (:n, :v);
- SELECT sql_id, child_number, executions
- FROM v$sql
- WHERE sql_text = 'INSERT INTO t (n, v) VALUES (:n, :v)';
- drop table t;
我们会发现最后一个select语句执行的结果如下图所示:
说明对应这条insert语句只生成了一个父游标,只是这个父游标被执行了3次。也就是除开第一次插入的时候,我们进行了硬解析。接下来2次,我们都进行的是软解析。
四. 绑定变量缺点
影响oracle选择效率低下的执行计划。
由于使用绑定变量,父游标和子游标都能共享重用(除开第一次硬解析,其他每次都是软解析)。子游标每次都重用(除开第一次),那么执行计划每一次都相同。假如子游标里面的执行计划确认进行的是全表扫描,因为第一次要查询这个表里面绝大部分数据,oracle认为执行全表扫描快。如果第二次只需要扫描很小一部分数据,执行索引扫描比较快的话。由于子游标重用,还执行的是全表扫描。我们可以看一个例子:
执行如下一段SQL文本:
- VARIABLE id NUMBER
- SET ECHO ON
- ALTER SYSTEM FLUSH SHARED_POOL;
- DROP TABLE t;
- CREATE TABLE t
- AS
- SELECT rownum AS id, rpad('*',100,'*') AS pad
- FROM dual
- CONNECT BY level <= 1000;
- ALTER TABLE t ADD CONSTRAINT t_pk PRIMARY KEY (id);
- BEGIN
- dbms_stats.gather_table_stats(
- ownname => user,
- tabname => 't',
- estimate_percent => 100,
- method_opt => 'for all columns size 1'
- );
- END;
- /
- EXECUTE :id := 990;
- SELECT count(pad) FROM t WHERE id < :id;
- SELECT * FROM table(dbms_xplan.display_cursor(NULL, NULL, 'basic'));
- EXECUTE :id := 10;
- SELECT count(pad) FROM t WHERE id < :id;
- SELECT * FROM table(dbms_xplan.display_cursor(NULL, NULL, 'basic'));
我们发现当 id=10, 也就是查询非常小部分数据的时候,仍然执行的是全表扫描,如下图:
五. 绑定变量使用场景
什么时候应该使用绑定变量,什么时候又应该避免呢?
我们可以看到,使用绑定变量主要是为了避免硬解析,也就是加快SQL的解析时间,但是有可能导致Oracle重用效率低下的执行计划。也就是延长SQL的执行时间。这个时候我们应该权衡,这条SQL是解析时间比较长还是执行时间。
1. 如果一次只处理小部分数据,解析时间等于或者高于执行时间,那么建议使用绑定变量。
2. 如果一次处理大批量数据,执行时间高于解析时间几个数量级,那么没必要使用绑定变量,加快那么一点解析时间微不足道。而且还有可能导致oracle重用效率低下的执行计划,大大影响SQL的执行速度。
发表评论
-
Oracle事务原理探究2--读书笔记五
2015-01-05 13:46 1703续上篇... 3. 数据块访问与undo ... -
Oracle事务原理探究1--oracle核心技术读书笔记五
2014-12-29 21:18 20281. 冲突解决 假如有一个系统只有你和我两个 ... -
oracle undo 复杂度--oracle核心技术读书笔记四
2014-10-01 14:23 1288一. 概述 undo ... -
Oracle redo 复杂度--oracle核心技术读书笔记三
2014-09-29 22:13 1190一. 概述 我 ... -
(转)undo系列学习之Oracle IMU及Redo Private Strands技术
2014-09-27 23:09 1169原博客地址: http://blo ... -
oracle如何保证事务的ACID原则--oracle核心技术读书笔记二
2014-09-21 11:18 1785在事务中有四个通用的原则是所有数据库都必须遵守的,简称ACI ... -
Oracle基本数据改变原理浅析(redo与undo)--oracle核心技术读书笔记一
2014-09-14 17:00 4845在oracle中我们做一些更新操作,oracle底层是怎么流 ... -
(转)Oracle中Hint深入理解
2014-01-07 19:48 1216原文出处:http://czmmiao.iteye.com/ ... -
Oracle全表扫描成本示例
2013-12-29 22:51 0一. 准备工作 1. block size 8KB( ... -
(转)Oracle查看trace文件步骤
2013-12-10 09:54 5447原文地址: http://www.2cto.com/data ... -
【转】CBO hint:no_unnest,push_subq,push_pred的用法
2013-12-02 20:11 1266原博客地址:http://blog.itpub.net/15 ... -
index_stats视图各列的含义
2013-12-02 19:10 1402index_stats视图来收集B树 ... -
(转)Oracle 调整SGA、PGA大小
2013-10-31 13:25 31218SQL> show parameter sga; ... -
(转)Oracle cursor_sharing 参数 详解
2013-08-25 23:04 1991原博客地址:http://blog.csdn.net/tia ... -
(转)shared pool 原理
2013-08-18 22:58 1490原博客地址:http://blog.csdn.net/ro ... -
(转)Oracle 游标(cursor)说明
2013-08-15 20:17 1493原博客地址:http://blog.csdn.net/ti ... -
(转)关于semi-join/anti-join的一点探讨
2013-08-14 21:20 11010原博客地址:http://space.itpub.net ... -
oracle 索引访问方式
2013-07-29 23:02 1467一. 概述 index uni ... -
(转)Oracle动态性能视图学习笔记(2)_v$sesstat_v$mystat_v$statname
2013-07-29 21:41 1215原博客地址:http://space.itpub.net/1 ... -
(转)Oracle性能优化 之 共享池
2013-07-29 21:04 1268转载作品,原始出去如下: http://blog.ch ...
相关推荐
Oracle游标是数据库编程中非常重要的一个概念,主要用于处理SQL查询的结果集。游标允许我们按行处理数据,逐条读取结果集,而不仅仅是一次性获取所有数据。在Oracle数据库中,游标对于复杂的事务处理、动态SQL以及...
Oracle数据库的绑定变量是一种优化策略,它在提升数据库性能、可扩展性和稳定性方面扮演着重要角色。绑定变量的使用能够显著改善SQL语句的执行效率,尤其是在处理大量重复查询时。本文将深入探讨绑定变量的原理、...
- **打开游标**:使用`OPEN`语句打开已声明的游标,这会基于绑定变量的值确定活动集,并将指针指向第一行。 ```sql OPEN cursor_name; ``` - **提取结果**:使用`FETCH`语句将查询结果提取到PL/SQL变量中。有两...
而 `FORCE` 则强制所有SQL语句都使用绑定变量,进一步减少解析次数。 此外,还有几个相关的视图用于监控游标状态: - `V$OPEN_CURSOR` 显示每个用户会话当前打开并解析的游标信息。 - `V$SQLAREA` 提供关于共享SQL...
打开游标(OPEN),解析,绑定,不会从数据库检索数据 - 从游标中获取记录(FETCH INTO),执行查询,返回结果集,通常定义局域变量作为从游标获取数据的缓冲区 - 关闭游标(CLOSE),完成游标处理,用户不能从...
在Oracle 9i及其以后的版本中,还增加了使用BULK COLLECT子句批量绑定数据和使用CURSOR表达式实现嵌套游标的功能。本章将主要介绍如何使用显式游标进行多行数据的查询、游标FOR循环以及游标变量的使用,另外还将介绍...
Oracle数据库系统中,游标和异常处理是两个关键概念,特别是在复杂的数据库操作和程序设计中。游标允许我们逐行处理查询结果,而异常处理则提供了错误管理的机制,确保程序在遇到错误时能优雅地恢复或终止。 首先,...
优化策略包括但不限于:使用合适的索引,避免全表扫描,减少子查询,使用JOIN代替子查询,合理使用绑定变量,以及优化数据类型选择等。此外,Oracle还提供了许多内置的工具,如Explain Plan和SQL Trace,帮助开发者...
标题与描述中的“SQL绑定变量”这一知识点,主要聚焦于SQL语句中如何使用变量,尤其是在存储过程或函数中动态构建SQL语句时的关键技术。绑定变量允许在SQL语句中使用程序变量作为参数,这不仅提高了代码的可读性和...
Oracle游标主要分为两大类:显示游标和隐式游标。其中,显示游标又可以根据定义方式的不同细分为静态游标和动态游标。 ##### 显示游标 显示游标主要用于处理SELECT语句的结果集。当定义游标时,需要明确指定SQL...
4. **绑定变量**:在Oracle中,绑定变量可以用来提高查询性能,减少解析次数。在批量插入时,可以使用绑定变量来存储多个值,然后在INSERT语句中重复使用。 5. **游标(Cursor)**:游标是处理结果集的有效工具,...
3. SQL优化:分析慢查询,使用EXPLAIN PLAN理解执行计划,通过绑定变量、物化视图、索引覆盖等方式优化查询性能。 4. 表空间设计:根据数据量和访问模式设计合理的表空间策略,如使用分区、分段等技术。 5. 内存管理...
- 使用绑定变量:绑定变量可以重用SQL语句的解析计划,减少游标开销。 - 减少显式游标使用:尽可能使用数据库提供的隐式游标,它们通常更高效且易于管理。 - 分析SQL性能:通过`V$SQL`视图分析SQL语句的执行情况...
3. 优化应用程序中SQL硬解析的频率,例如通过绑定变量来避免不必要的硬解析。 4. 分析v$librarycache视图中的数据,找出那些频繁被重新加载的对象,并考虑修改应用程序逻辑以减少其影响。 5. 考虑使用Oracle的自动...
1. **Oracle游标**: - 游标允许我们处理查询结果集中的一行数据,分为显示游标和隐式游标。 - 显示游标通过`cursor...is`语句定义,可以显式管理和控制查询结果集,适用于处理多条记录。 - 隐式游标则是由PL/SQL...
父子游标详解 父子游标是 Oracle 中的一种机制,用于优化 SQL 语句的执行。它通过共享游标来减少开销,提高系统性能。...但是,软解析和硬解析需要根据实际情况进行选择,绑定变量和优化器也需要仔细斟酌。
3. **游标和绑定变量**:游标是Oracle中的一个关键概念,用于处理结果集。Pro*C中使用游标来逐行处理查询结果,而绑定变量则用于在SQL语句中传递参数,提高性能并减少SQL注入的风险。 4. **异常处理**:Oracle提供...
- 讨论了绑定变量的使用,包括按名称或位置绑定参数,绑定方向,绑定NULL值,ROWID值,DML RETURNING绑定变量,LOB绑定变量,REF游标绑定变量,以及如何绑定PL/SQL集合和记录。 ### 结论 文档内容涉及了cx_Oracle...
为了优化执行计划,我们可以使用绑定变量、减少硬解析、配置 session_cached_cursors、高速缓存游标等方法。 绑定变量 使用绑定变量可以减少硬解析的数量。例如,在 SQL 语句中使用绑定变量 `:empno` 代替硬编码的...