探讨SELECT语句的元数据&动态取样&读一致性导致的一致性读和递归操作

前几天,论坛上的同行在讨论SELECT语句的元数据,动态取样和读一致性导致的一致性读和递归问题,今天有时间,就试着进行了测试,本人测试环境如下:

win7_64+Oracle11.2.0.4_64

那么,下面就说下测试过程:

1、元数据:当用户向数据库发出SELECT语句后,在解析和执行过程中,肯定是需要读取SELECT相关的元数据,这样,SELECT的统计数据中就会包含递归操作,做这个测试的前提是要把其他因素排除掉(动态取样,一致性读):

session1:

session2:

由上可见,在表没有任何数据块分配和取样的前提下,SELECT语句解析执行过程中,还是发生了递归,而且期间产生的读取,并未计入该语句的统计数据中。

2、读一致性:当我们往表里插入数据后,表分配了一些数据块,在没有动态取样情况下,发生了读一致性,发生的一致性读的数量等于需要读取的表的数据块和undo块的数量。

session1:

session2:

这里,为什么说cr的数量等于表数据块加上undo数据块呢?因为当session1中提交时,session2中的cr数量要少很多,那时,在没有其他并发修改操作的情况下,就不再需要读取undo块,大家有时间可以测试下,这里不再贴出测试过程。

3、动态取样:在表数据量不变和发生动态取样的情况下,当有动态取样发生时,cr和无动态取样发生时有较大差别,这说明动态取样虽然导致了递归的发生,但其中发生的cr也被计入了查询语句的统计数据中。

session2:

以上我们通过hint强制查询语句在解析运行时发生level为8的动态取样,可见发生了递归操作,而cr也有相应增加,而当我们再次运行该语句时,因为不需要再次解析,所以,也就没有了动态取样,因此,此时cr有所降低。

4、redo:我们还注意到,在session1中往表中插入数据但没提交的情况下,session2中select该表时,会产生redo数据,并且,经过进一步测试,这些redo数据也确实写入了redo log file中。

那么,这个redo size是怎么产生的呢?也许有人会说延迟块清除,但是,这里session1中插入的数据并未提交,而且,每次执行select语句,都会有几乎等量的redo产生,这和延迟块清除不同。延迟块清除只有在数据提交后,第一次查询时会产生redo数据,再次查询就不会发生,而且产生的redo也不会这么多。仔细想想,唯一的可能就是,在利用undo数据构造cr块的过程中,也记录了对这些db block的redo数据,并写入了redo log file中,目的就是万一系统此时发生崩溃,再次重启时,通过redo log file中的redo数据重构内存中的这些cr块。

以上为个人测试和临时的想法,仅供大家参考。

原文地址:https://www.cnblogs.com/lhdz_bj/p/9054680.html

时间: 2024-10-12 22:24:22

探讨SELECT语句的元数据&动态取样&读一致性导致的一致性读和递归操作的相关文章

oracle 隐式游标,显示游标,游标循环,动态SELECT语句和动态游标,异常处理和自定义异常

游标的概念:    游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁 盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库.这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率.游标有两种类型:显式游标和隐式游标.在前述程序中用到的SELECT...INTO...查询语句,一次只能从数据库中提取一行数据,对于这种 形式的查询和DML操作,系统都会使用一个隐式游标.但是如果要

程序架构探讨—001 多段select语句的方案

有时候,我们需要做多条件查询,多个条件为"或"的关系,分类查询等,一般会用到多段select语句,然后用union或者union all进行连接,进而查出需要的结果. 例如, select a.id as id, a.name as name, a.age as age from scama.table_name2 a where 1=1 union all select b.sn as id, b.name as name, b.age as age from scama.table

程序架构探讨—001 查询语句中多段select语句的方案

有时候,我们需要做多条件查询,多个条件为"或"的关系,分类查询等,一般会用到多段select语句,然后用union或者union all进行连接,进而查出需要的结果.例如,select a.id as id,a.name as name,a.age as agefrom scama.table_name2 awhere 1=1 union all select b.sn as id,b.name as name,b.age as agefrom scama.table_name2 bw

生成动态SQL_insert update select 语句

快速生成insert update select 语句 declare sText VARCHAR2(3000); sTable varchar2(30); begin sTable := '&Tablename'; select get_sql_insert(sTable) INTO sText from dual; DBMS_OUTPUT.put_line(sText); DBMS_OUTPUT.put_line(''); DBMS_OUTPUT.put_line(''); select g

Local prefixed index和Local nonprefixed index对select语句的性能影响分析

1.搞清楚两种索引的概念 在比较两种索引对select产生的影响之前,先要搞清楚,什么是Local prefixed index,什么叫Local nonprefixed index.其实,这两种索引,都是属于分区local索引,所以,这两种类型的索引,只有可能在分区表上才会出现. 1.1 什么是Local prefixed index 是指索引中的列,就是分区表的分区键列,或者是索引中的列,包含表的分区键值列,并且为前置位 置在索引最前部位置的本地分区索引. 例如,emp表是按时间范围分区的表

SQL Server数据库培训(SQL篇)----Select语句构成元素

1.             Select语句构成元素 1.1          Select * 避免使用select * 当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 '*' 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,SQL在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间. 1.2          Select语句中元素的执行顺序 为了描述逻辑查询处理和各种SELECT查询子句

优化Select 语句的原则

优化Select 语句的原则 -摘抄<SQL Server 2005 性能监测与优化> Select 语句是数据库应用系统中最常用的语句之一,Select 语句设计的好坏直接影响到应用程序的工作性能. 在设计Select语句时,应该注意以下几种影响查询效率的情况: 1.  没有创建索引,或者没有正确地使用索引.这是最有可能影响数据库查询的原因之一.创建索引是优化数据库查询效率的重要手段. 2.  存在死锁的情况,从而导致Select语句挂起,无法返回结果集. 3.  返回不必要的列,很多程序员

常用Select语句

--语 句                                功 能--数据操作SELECT      --从数据库表中检索数据行和列INSERT      --向数据库表添加新数据行DELETE      --从数据库表中删除数据行UPDATE      --更新数据库表中的数据--数据定义CREATE TABLE    --创建一个数据库表DROP TABLE     --从数据库中删除表ALTER TABLE     --修改数据库表结构CREATE VIEW     --创建

8.2.1-优化SELECT语句

8.2.1.优化 SELECT 语句 由SELECT 语句组成的查询,在数据中执行所有的查询.对这类语句的调优排在首位,无论是调优动态web网页的二级响应时间,还是减少生成巨大隔夜报告的时间. 而且,对SELECT语句调优的技术同样适用 CREATE TABLE...AS SELECT, INSERT INTO...SELECT,DELETE 中带有where的语句.这些语句还有其他的性能开销,因为这些操作在读操作的时候也进行写操作. MySQL Cluster 支持join pushdown优