知识大全 显式游标范围大小和复杂间隔的相关问题介绍

Posted

篇首语:前事不忘,后事之师。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 显式游标范围大小和复杂间隔的相关问题介绍相关的知识,希望对你有一定的参考价值。

   我们的技术专家回答关于游标 范围(extent)和间隔的问题   是不是从Oracle 第 版以后的版本 隐式游标得到了优化 不会两次取数据?还有 为什么当表T在列X上有一个索引时下面的隐式游标比显式游标运行得更快 而没有索引时是显式游标运行得较快呢?    Implicit Cursor:  Select x  into y  from T  where x = j;    Explicit Cursor:  cursor c(p number) is  select x from blah where x = p;  open c(j);  fetch c into y;  close c;    为了让每个人都了解显式游标和隐式游标是什么 我先简单介绍一下它们的定义     通常 隐式游标是指程序员并不 显式 声明 打开 从中取数据和关闭的那些游标 这些操作都是隐式的 因此 在上面的例子中 SELECT X INTO Y查询就是一个隐式游标 对于它来说并没有 cursor cursor_name is 这样的定义语句 相反 第二个例子是典型的显式关标 程序员显式地声明 打开 取数据和关闭它     在PL/SQL中隐式游标比显式游标运行得更快是一个事实 在Oracle 版之前的版本中就是这样 事实上 我在Oracle 版中就测试过这样的情况并得到了同样的结论(这些测试请参见/~tkyte/l) 隐式游标运行得更快的原因(FOR LOOP隐式游标和SELECT INTO隐式游标)是PL/SQL引擎只需要解释和执行很少的代码 一般来说 PL/SQL引擎在后台做的越多 程序就运行地越快 上面的隐式游标只使用了一行PL/SQL代码 显式游标至少使用了三行代码 如果要 正确地 运行 实际上要使用 行代码 你的显式代码并不像隐式游标那样运行 它要确保你得到一条且只得到一条记录 你的显式代码缺少了许多你要做的工作 为了精确地比较你的两个游标例子 你的显式代码应该被扩展出以下几行     open c(j);  fetch c into y;  if ( c%notfound ) then raise NO_DATA_FOUND;  end if;  fetch c into y;  if ( c%found ) then raise TOO_MANY_ROWS;  end if;  close c;    如果这就是你的显式游标 你会发现在所有情况下显式游标都运行得比较慢 甚至于无论你的例子中有没有索引都是这样     那么 你的问题的症结所在是 为什么在你的例子中没有索引时 隐式游标好像运行地非常慢 然而当存在一个索引的时候 隐式游标却运行得较快呢?答案在于全表扫描 事实上在得到一条记录后 你的显式测试就停止了 我将给出一个例子来向你展示它们之间的不同之处     SQL> create table t ( x int )    pctfree pctused ;  Table created     SQL> insert into t    select rownum     from all_objects;   rows created     SQL> analyze table t pute statistics;  Table analyzed     SQL> select blocks empty_blocks num_rows     from user_tables     where table_name = T ;    BLOCKS   EMPTY_BLOCKS   NUM_ROWS                          我创建了一个有许多数据块的表 值pctfree 为随后更新数据保留了 %的块作为 空闲空间 因此 即使表中的数据量很小 表本身也相当大 接着 我通过INSERT把值 一直到 严格按顺序插入到表中 因此 X= 在该表的 第一个 块中而X= 在表中相当接近表的最后一个块     接下来 我将运行一个小PL/SQL块 它会显示各种隐式和显式游标对数据进行一致读的次数 因为没有索引 查询将对整个表进行全面扫描 一旦我运行这个程序然后评审查询结果 将很容易对性能的差异进行量化     SQL> declare      l_last_cgets number default ;      l_x   number;      cursor c( p_x in number ) is      select x      from t        where x = p_x;       procedure cgets( p_msg in varchar   )    is     l_value number;    begin     select b value into l_value      from v$statname a v$mystat b      where a statistic# = b statistic#       and a name = consistent gets ;        dbms_output put_line( p_msg );     dbms_output put_line     (  Incremental cgets: ||      to_char(l_value l_last_cgets                ) );     l_last_cgets := l_value;    end;       begin     cgets( Starting );        open c( );     fetch c into l_x;     close c;     cgets( Explicit to find X= ||           stop at first hit );        open c( );     fetch c into l_x;     fetch c into l_x;     close c;     cgets( Explicit to find X= ||           check for dups );        select x into l_x      from t      where x = AND rownum = ;     cgets( Implicit to find X= ||           stop at first hit );        select x into l_x      from t      where x = ;     cgets( Implicit to find X= ||           check for dups );        open c( );     fetch c into l_x;     close c;     cgets( Explicit to find X= );        select x into l_x         from t         where x = ;     cgets( Implicit to find X= );    end;    /  Starting  Incremental cgets:    Explicit to find X= stop at first hit  Incremental cgets:  &nb  sp;    Explicit to find X= check for dups  Incremental cgets:     Implicit to find X= stop at first hit  Incremental cgets:       Implicit to find X= check for dups  Incremental cgets:     Explicit to find X=   Incremental cgets:     Implicit to find X=   Incremental cgets:       PL/SQL procedure successfully pleted     现在你就可以明白在你的例子中为什么显式游标好像比隐式游标运行得更快了 当我使用显式游标进行测试的时候 只取一次数据X= 为了找到答案 查询只需要扫描非常少的块(很少的一致的读次数) 然而 只要我使显式游标来进行隐式游标的工作 检查确保没有其他记录满足同一条件 你就会看到显式游标检查表中的每一个块 现在 我接着说隐式游标 通过使用ROWNUM= 看看它是否也会在找到第一条符合条件的记录时停下来 它和显式游标做相同的工作量 当它检查表中的第二行是否符合条件时 你会看到它同显式游标一样进行相同次数的一致读 它也不得不对表进行全面扫描以核定只有一行X=     最有趣的是当我查询X= 的时候 因为那行接近表的 结尾 所以无论我采用什么方法 两个查询的工作量都差不多 为了找到满足条件的第一行它们都必须扫描几乎整个表     现在 如果在X上有一个索引 两个查询都会使用索引范围扫描 而且两个查询都不必对表进行全面扫描 便能快速地发现只有一行满足条件     这就解释了你的游标行为 SELECT INTO检查第二行 但显式游标却不这么做 如果你对应地进行比较 第二次显式地取数据或者把 rownum = 添加到SELECT INTO语句中--你就会发现两个游标的工作量相同     简而言之 隐式游标更好 它们比使用显式游标的相同代码运行地更快 更容易编码(需要键入的代码更少) 而且我个人认为使用隐士游标的代码更容易读也更容易理解      小 中和大  在我们的新应用程序中 我们设计了数据库并创建了数据模型 甚至还估计了表的大小并为每个标指定了存储参数 但现在我们的数据库管理员告诉我们将给我们三个表空间 范围大小统一为 K的TS_small表空间 范围大小统一为 MB的TS_med表空间和范围大小统一为 MB的TS_large表空间 他们告诉我们在TS_small中创建小于 MB的表 在TS_med中创建小于 MB的表 在TS_large中创建大于 MB的表 另外 他们不希望我们对表使用任何存储参数 对索引也是这样 这好像并不合理 因为对于一个预计大小为 MB的表 我们应把它放在TS_med中 接下来如果我们在那个表空间中创建它 它会占 个范围!数据库管理员声称许多测试已经证明这种设计提供了最佳的性能并可以防止碎片 我的问题是 他们说的对吗?我担心对象会有太多的范围     看来他们已经读过asktom Web站点()和互联网讨论组的相关内容 并发现了好的建议 从他们的数字看 我注意到他们允许一个表占用的最大空间是 GB 可以有 个或更少的范围 假设上百个(或者上千个)范围不会影响运行时数据操纵语言(DML)的性能 我会说他们做得非常好     他们的前提都是正确的 cha138/Article/program/Oracle/201311/16936

相关参考

知识大全 Oracle游标提取相关的数据的语法介绍

Oracle游标提取相关的数据的语法介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文主要

知识大全 关于约束、CASE语句和游标的一些介绍

关于约束、CASE语句和游标的一些介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  关于约束C

知识大全 Sql中游标和加锁的问题分析与解答

Sql中游标和加锁的问题分析与解答  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!    <%

知识大全 介绍Oracle使用游标触发器存储实操

介绍Oracle使用游标触发器存储实操  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  如果你在O

知识大全 用一个实例讲解DB2数据库游标循环的问题

用一个实例讲解DB2数据库游标循环的问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文中的

知识大全 ps里修复画笔工具在涂抹的时候有圆圈 为什么还有个十字游标,怎样去掉这个十字

ps里修复画笔工具在涂抹的时候有圆圈为什么还有个十字游标,怎样去掉这个十字圆圈确定范围,十字游标一般用于小尺寸的精确操作,切换按键是CapsLockps中的修复画笔工具的使用时多出的十字影响效果看样子

知识大全 深入讲解游标类型为什么会产生数据检索[1]

  游标类型产生的数据检索问题  现象:  在将数据库兼容的级别从改到以后下文中的游标循环不出数据单独SELECT却会有结果:  DECLAREMyCursorCURSORLOCALREAD_ONLY

在检查手外伤伤口时应注意的问题?

在检查手外伤伤口时应注意伤口的部位、大小、深度及范围,伤口的污染程度及时间以及损伤的性质。了解伤口的部位可估计易损伤的组织;了解伤口的大小及性质,可确定损伤的程度和范围;了解伤口污染的程度和时间,可估

知识大全 oraclePL/SQL之隐式游标和ref游标总结

oraclePL/SQL之隐式游标和ref游标总结  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 请解释接口的显式实现有什么意义

cha138/Article/program/ASP/201405/30778