Recent Posts

RSS Feeds

关于DBA日记的更新

DBA日记共写了两部《Oracle 优化日记》和《Oracle RAC日记》这两部目前已经由机械工业出版社出版。

本来老白想继续写第三部的,不过最近想写《Thinking  in Oracle》系列的念头十分强烈,因此暂时放弃DBA日记系列的写作,开始《Thinking  in Oracle之一 DBA的思想天空》的写作工作。这部分内容在www.oraclefans.cn上面不定期连载,目前已经连载了几十篇了。

请大家到www.oraclefans.cn上的DBA日记板块去阅读,这个博客将不再更新了。请大家原谅

Permalink     2 Comments

Thinking in Oracle 之DBA的思想天空 3.3.8 CPU_COUNT引起的共享池问题

请到ORACLEFANS论坛阅读:

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=32821

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月10日 理解分区表(1) 什么是分区表

请到www.oraclefans.cn去阅读:

 

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=24424&CPages=1

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月9日理解REDO LOG(5) BULK 操作能减少REDO吗?

请到oraclefans网阅读:

 

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=23654

另外,本节将结束。下面写点什么好呢?请大家多提建议

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月8日理解REDO LOG(4) 日志切换和REDO LOG文件

请到www.oraclefans.cn阅读:

 

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=23503

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月6日理解REDO LOG(3) LOG BUFFER 和LGWR

请到ORACLEFANS网查看:

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=23409

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月5日理解REDO LOG(2) 变化矢量和REDO RECORD

请到ORACLEFANS网阅读:

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=6451&CPages=1

 

Permalink     No Comments

DBA日记第三部 4月4日理解REDO LOG(1) 介质恢复和实例恢复的基本概念

请参考:

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=23315

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月2日 索引危机(3)效果不错

请到下列链接阅读

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=22114&CPages=1

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月2日 索引危机(2)索引范围扫描的优化方法

请到下面网页阅读:

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=19756

 

在这里老白做个广告:

DBA日记第二部实体书《ORACLE RAC日记》已经由人民邮电出版社出版,请到下列地址订购:

  http://www.china-pub.com/50901

http://item.taobao.com/auction/item_detail.htm?item_num_id=5059262372

DBA日记第一部实体书《Oracle优化日记》6月13日正式出版,敬请关注

 

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 4月1日 索引危机(1)不能修改应用的项目

请到oraclefans网阅读:

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=19716&CPages=1

 

Permalink     No Comments

DBA日记第三部 像Oracle一样思考 3月29日 理解索引(3)索引访问的方式

330日 理解索引(3)索引访问的方式

设计索引是专业性很强的工作,一般来说索引设计最好有专业DBA参与,不过现实中,绝大多数系统的索引设计都是由开发人员完成的。由于开发人员对索引的原理不甚了解,因此在大多数软件系统中索引设计方面都存在很大的问题。Oracle公司有一门培训课程叫做《开发DBA》,这门课程的主要目的是让开发人员理解一些Oracle的基本原理与概念,从而在设计应用系统的时候可以依据这些原理,避免出现一些严重的问题。在开发人员中进行类似《开发DBA》这样课程的培训,是数据库优化工作中十分重要的环节,而这个环节往往被我们所忽视。实际上,在研发团队进行适当的培训,可以大量节省的成本。

今天我们要讨论的话题是如何设计索引,这是很多DBA都很想了解的。实际上昨天我们也讨论到了设计索引的一些基本的方法。索引的设计要遵循一些最基本的原则,首先,索引的设计必须是有针对性的,索引的目的是快速定位数据,因此每个索引都必须符合快速定位数据的要求。比如说我们想让下面的一条语句执行的更快一些,消耗更小的资源:

select emp_name,emp_id,sal from emp where emp_id=11023

首先我们需要分析一下emp这张表,emp表是企业的职员表,有数万条记录,而每个职员都有唯一的EMP_ID对应,那么如果我们在EMP_ID上创建了索引,那么这个SQL就可以通过索引快速定位到EMP_ID,然后通过索引中的ROWID直接找到EMP表中的相关记录,并取出所需要的数据。这种情况下,在EMP_ID上创建一个索引就是十分必要的。我们再来看下一个语句:

select emp_id,sal from emp where emp_id=11023 and emp_name like 'John%'

在这个语句中,WHERE条件有两个,一个是emp_id=11023,另外一个是emp_name likje 'John%'。这个时候oracle该如何来选择合适的执行计划呢?我们讨论的前提是使用CBO优化器(RBO优化器在索引选择的时候智能程度很低,出现执行计划错误的机会要比CBO大得多,因此建议在有可能的情况下,尽可能使用CBO),在使用CBO的情况下,CBO会根据索引的统计数据计算每个索引访问路径的成本,从而选择一种开销较小的执行计划。在这个案例中,我们可以简单的来分析一下。如果通过EMP_ID来查找相关的数据,EMP_ID是主键,根据EMP_ID=11023可以唯一定位到一条记录,然后我们可以取出这条记录的SALEMP_NAMEEMP_ID这三个字段的值,将EMP_NAME字段的值和WHERE 条件中的emp_name like 'John%'进行比较,如果这条记录符合这个条件,就返回这一条记录,如果这条记录不符合,那么就没有记录返回了。

下面我们来分析一下另外一条访问路径,如果我们使用EMP_NAME上索引,首先找到所有的emp_name like 'John%'的记录,也许我们能找到10条记录,通过索引中提供的10条记录的ROWID,再去访问这张表,把emp_id,sal这两个字段的值取出来,然后我们再通过另外一个过滤条件emp_id=11023进行筛选,把符合条件的记录找出来。很明显,我们可以发现这条访问路径的开销要比第一条略高,因为我们先查出了10条记录,然后再通过过滤器过滤掉了其中的9条,而第一种执行计划只检索了一条记录就获得了结果。

第三种访问路径就是我们所说的全表扫描,如果在EMP_NAMEEMP_ID上都没有创建索引,那么我们必须对这张有几万条记录的表从头到尾扫描一遍,找到所有符合上面两个过滤条件的记录,并把对应的EMP_IDSAL值检索出来。

这三条访问路径到底哪个开销更小呢?实际上ORACLECBO优化器会自动计算访问路径的成本,并且选择最佳的路径来执行这个SQL。实际上我们的例子里包含Oracle访问数据的三种常见的方法,第一种是索引唯一性检索,通过唯一性索引定位到某条记录,读出该记录后通过emp_name这个过滤条件进行筛选,最后获得符合条件的所有记录。第二条路径是通过emp_name上的索引找出所有符合条件的记录,这种查找方式是找到符合条件的第一条记录,然后顺着叶节点链按照升序或者降序的方式扫描出所有符合条件的记录的ROWID,然后依次将表中的相关数据块读出来,根据其他的过滤条件进行筛选,找到符合条件的记录,这种方式也就是我们常说的索引范围扫描。第三种方法是直接读取表的数据,将数据读出后,根据emp_idemp_name两个条件进行过滤,获得所需要的数据。

另外还有一种数据访问路径,在这个案例中看不到,这种方法是Oracle 9i开始支持的。比如我们有一个复合索引IDX_ID_NAME,这个索引包含两个字段EMP_IDEMP_NAME,而有这样一个SQL:

select emp_id,sal from emp where  emp_name= 'John'

 

这种情况下,我们可以通IDX_ID_NAME来查找所需要的数据。由于这个索引中,EMP_NAME不是这个索引的第一个字段,因此在扫描索引的时候无法像普通的UNIQUE 或者RANGE SCAN一样,通过一次定位,然后顺着叶节点链进行扫描。这种扫描必须是跳跃式的,因为这个索引的前导字段是EMP_ID,因此扫描的时候,对于每个EMP_ID,都需要做一次定位,然后通过叶节点链查找到所有符合条件的记录。Oracle也给这种扫描方式起了一个很形象的名字:INDEX SKIP SCAN,中文翻译一般使用“索引跳跃式扫描”。INDEX SKIP SCAN是一种跳跃式的扫描方式,因此分段的数量对于扫描的成本影响很大,本案例中EMP_ID是主键,在这种情况下,使用INDEX SKIP SCAN的成本实际上是比较高的,其成本开销甚至会高于索引全扫描。

刚才我们又引入了另外一种索引访问的方式,索引全扫描。索引全扫描有两种不同的方式。一种被称为索引全扫描(INDEX FULL SCAN),另外一种被称为索引快速全扫描(INDEX FAST FULL SCAN)。为什么要使用索引全扫描呢?我们先看一个SQL

select emp_name from emp where emp_name is not null

emp_name上有一个索引,我们知道索引中包含了所有emp_name不为空的值,因此这种情况下,只要对整个索引进行一次扫描就可以完成这个SQL了,而不需要对表做全表扫描。一般来说,对于字段较多的表,索引的大小会远小于表的大小,因此全索引扫描的成本会远小于全表扫描的大小。上述这个例子中,可以使用索引快速扫描,对索引的扫描可以根据该索引的extent来进行,采用多块读的方式进行。因此在这类操作中,我们可以看到会话会大量的出现db file scattered read等待。我们经常看到db file scattered read等待就说系统中出现了全表扫描,其实这种说法并不准确,因为索引快速全扫描也会使用多块读的方式来扫描。

如果我们对SQL进行一些小的修改:

select emp_name from emp where emp_name is not null order by emp_name

那么SQL的执行路径可能会有所改变,不使用索引快速全扫描。索引快速全扫描是根据EXTENTS的顺序的,不是按照EMP_NAME的值的大小进行的,因此这样扫描出来的emp_name数据不是按照emp_name排序的,如果要排序,必须对索引的扫描完成后再进行一次排序。这样的执行计划可能不如另外一种索引扫描的方式-索引全扫描,索引全扫描和索引快速全扫描不同的地方是,索引全扫描是根据叶节点链来进行的。进行索引全扫描首先要从根开始,找到叶节点链上的第一个数据块,然后沿着叶节点链进行扫描,由于叶节点链是根据索引键值排序的,因此这样扫描出来的数据本身就是排序的,数据读出后不需要再次排序。这种扫描方式和索引快速全扫描相比,首先要找到索引的根,然后通过枝节点找到第一个叶节点,然后再顺着叶节点链扫描整个索引。索引全扫描的IO成本比索引快速全扫描要大很多,读取根节点和叶节点的成本相对不大,不过由于顺着叶节点链扫描整个索引的时候无法使用多块读,而只能使用单块读,因此这种扫描方式的IO开销要远大于索引快速全扫描。这种索引扫描,我们如果对会话进行跟踪,会发现大量的db file sequential read等待。

在这里,大家可能会有一个疑问,带ORDER BYSQL语句是否一定使用索引全扫描成本小于索引快速全扫描呢?实际上这也不能一概而论,关键要看排序操作的成本是否大于索引单块扫描比索引多块扫描两种扫描方式之间的IO成本差。

谈到这里,我们已经基本了解了索引访问的主要的方式,实际上还有一种索引的访问操作我们还没有讨论,就是位图索引的访问。由于位图索引的结构十分特殊,位图索引没有枝节点,是一种平面结构,因此如果我们想要通过位图索引进行扫描,只有一种扫描方式,这种访问方式类似于普通索引的索引快速全扫描,就是将索引按照EXTENTS,通过多块读进行扫描,这是因为位图索引的每个数据块中都可能包含我们所需要的键值。

 

Permalink     No Comments

这几天挺烦,DBA日记好久没更新了,大家原谅

这几天烦人的事情比较多,又经常半夜被电话吵醒。所以很少在网上发言,DBA日记也好久没更新了。可能是40多岁了,体力确实不如前些年,碰到一些比较复杂的问题,也不如前些年那样感到兴奋了。国内做DBA的环境和国外相差甚大,在国外,DBA做到40多岁,应该是最成熟的时期,事业有成,不必要为生活而忧虑,可以一心做些自己想做的事情了。在国内这方面就差了很多,我虽然现在也算衣食无忧,不过也不敢得罪任何一个衣食父母,因此还无法像庄子一样随心所欲。

这几天事情很多,感觉很疲乏,所以上网也希望聊些不需要动脑子的,不想讨论太深入的问题,可能怠慢了一些网友,在这里老白给大家道个歉了。前天晚上回到家里,一进家门,老婆就问我一个比较头疼的问题。我马上说,今天晚上谁都别和我说话。因为我知道,这种精神状态下,一旦几句话说的不和我的胃口,我就可能会发火。

 

实际上,这也是DBA生活的一部分,不仅仅像DBA日记里老白所说的那么阳光灿烂,等有时间,我也许也应该把这部分情感写出来和大家分享。

Permalink     5 Comments

DBA日记第三部 像Oracle一样思考 3月29日 理解索引(2)反转键索引的误区

请到下列网址查阅:

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=18643

 

由于这个BLOG系统对于较长的文档排版存在问题,因此暂时只发链接。不便之处请原谅

Permalink     1 Comment

DBA日记第三部 像Oracle一样思考 3月28日 理解索引(1)

请到ORACLE粉丝网上阅读

http://www.oraclefans.cn/forum/showtopic.jsp?rootid=18555

Permalink     No Comments