版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、通过分析SQL语句的执行计划优化SQL通过分析SQL语句的执行计划优化SQL第1章 性能调整综述第2章 有效的应用设计第3章SQL语句处理的过程第4章 ORACLE的优化器第5章 ORACLE的执行计划 访问路径(方法) - access path表之间的连接 如何产生执行计划 如何分析执行计划 如何干预执行计划 - - 使用hint膊s提示 具膊体案例分析第1章 性能缝调整综述 Oracle各数据库是高度可调的数据各库产品。本章描述调整的过各程和那些人员应与Oracle各服务器的调整有关,以各及与调整相关联的操作系统各硬件和软件。本章包括以下各方面: 谁来调整系技统? 什么时候调整诡? 建立
2、有效调整的厄目标 在设计和开发酒时的调整 调整产品酒系统 监控产品系统伐 谁来调整系统: 呆为了有效地调整系统,若鲍干类人员必须交换信息并牵鲍涉到系统调整中,例如: 溅 应用设计人员必须溅传达应用系统的设计,使得溅每个人都清楚应用中的数据溅流动. 应用开发玻人员必须传达他们选择的实玻现策略,使得语句调整的过玻程中能快速、容易地识别有玻问题的应用模块和可疑的SQl玻语句. 数据盯库管理人员必须仔细地监控盯系统活动并提供它们的资料贩,使得异常的系统性能可被贩快速得识别和纠正. 扮 硬件/软件管理人员必扮须传达系统的硬件、软件配扮置并提供它们的资料,使得扮相关人员能有效地设计和管扮理系统。 简而言之
3、,扁与系统涉及的每个人都在调扁整过程中起某些作用,当上扁面提及的那些人员传达了系扁统的特性并提供了它们的资扁料,调整就能相对的容易和扁更快一些。 不幸的叮是,事实上的结果是:数据叮库管理员对调整负有全部或叮主要的责任。但是,数据库叮管理员很少有合适的系统方叮面的资料,而且,在很多情断况下,数据库管理 员往往骸是在实施阶段才介入数据库骸,这就给调整工作带来许多骸负面的影响,因为在设计阶骸段的缺陷是不能通过DBA骸的调整而得以解决,而设计骸阶段的缺陷往往对数 据库出性能造成极大的影响。 头其实,在真正成熟的开发头环境下,开发人员作为纯代头码编写人员时,对性能的影头响最小,此时大部分的工作维应 由应
4、用设计人员完成,维而且数据库管理员往往在前维期的需求管理阶段就介入,维为设计人员提供必要的技术维支持。调整并不是数据库管维理员的专利,相反大部分应维该是 设计人员和开发人员维的工作,这就需要设计人员污和开发人员具体必要的数据污库知识,这样才能组成一个污高效的团队,然而事实上往污往并非如此。 什么时瞻候作调整? 多数人夜认为当用户感觉性能差时才夜进行调整,这对调整过程中夜使用某些最有效的调整策略夜来说往往是太迟了。此时,夜如果你不愿意重新设计应用夜的话,你只能通过 重新分夜配内存(调整SGA)和调夜整I/O的办法或多或少地夜提高性能。Oracle提议供了许多特性,这些特性只议有应用到正确地设计的
5、系统议中时才能够很大地提 高性议能。 应用设计人员需雍要在设计阶段设置应用的性雍能期望值。然后在设计和开徐发期间,应用设计人员应考徐虑哪些Oracle 特性徐可以对系统有好处,并使用徐这些特性。通过良好的系统徐设计,你就可以在应用的生徐命周期中消除性能调整的代徐价和挫折。当然,即使在设徐计很好的系统中,也可 能徐有性能降低。但这些性能降徐低应该是可控的和可以预见粘的。 调整目标 婶不管你正在设计或维护系统婶,你应该建立专门的性能目婶标,它使你知道何时要作调梨整。如果你试图胡乱地改动梨初始化参数或SQl语句,梨你可能会浪费调整系统的时梨间,而且无什么大的收益。梨调整你的系统的最有效方法梨如下:
6、当设计系涕统时考虑性能 调赎整操作系统的硬件和软件 赎 识别性能瓶颈 尿 确定问题的原因 类 采取纠正的动作 术当你设计系统时,制定专术门的目标;例如,响应时间术小于秒。当应用不能满足术此目标时,识别造成变慢的术瓶颈(例如,I/O竞争)术,确定原因,采取纠正动作术。在开发期间,你应测试应术用研究,确定在采取应用之术前是否满足设计的性能目标术。 当你正在维护生仟产库系统时,有多种快速有仟效的方法来识别性能瓶颈。仟不管怎样,调整通常是一系仟列开销。一旦你已确定了瓶仟颈,你可能要牺牲一些其它仟方面的指 标来达到所要的仟结果。例如,如果I/O有仟问题,你可能需要更多内存瞒或磁盘。如果不可能买,你瞒可能
7、要限制系统的并发性,瞒来获取所需的性能。然而,瞒如果你已经 明确地定义了瞒性能的目标,那用什么来交瞒换高性能的决策就变的很容瞒易的,因为你已经确定了哪瞒些方面是最重要的,如过我瞒的目标为高性能,可能牺牲瞒一些空间资 源。 随叁着应用的越来越庞大,硬件叁性能的提高,全面的调整应叁用逐渐变成代价高昂的行为叁,在这样情况下,要取得最叁大的投入/效率之 比,较叁好的办法是调整应用的关键叁部分,使其达到比较高的性叁能,这样从总体上来说,整临个系统的性能也是比较高的临。这也就是有名的20/80临原则,调整应用的 20%(临关键部分),能解决80%临的问题。 在设计葬和开发系统时作调整 漾 良好设计的系统可
8、以防止漾在应用生命周期中产生性能漾问题。系统设计人员和应用漾开发人员必须了解Oracle漾的查询处理机制以便写酝出高效的SQl语句。“第酝2 章 有效的应用设计”酝讨论了你的系统中各种可用酝的配置,以及每种配置更适酝合哪种类型的应用。“第4酝章 优化器”讨论了Oracle酝的查询优化器,以及酝如何写语句以获取最快的结酝果。 当设计你的系统裔时,使用下列优化性能的准裔则: 消除客户机犹服务器应用中不必要的网犹络传输。- 使用存储过犹程。 使用适合你执系统的相应Oracle服执务器选件(例如,并行查询执或分布式数据库)。 直 除非你的应用有特殊的直需要,否则使用缺省的Oracle直锁。 利浙用数据
9、库记住应用模块,以浙便你能以每个模块为基础来浙追踪性能。 选择蔗你的数据块的最佳大小。 - 蔗原则上来说大一些的蔗性能较好。 分布朽你的数据,使得一个节点使朽用的数据本地存贮在该节点朽中。 调整产品系统夷本节描述对应用系统快碌速、容易地找出性能瓶颈,碌并决定纠正动作的方法。这碌种方法依赖于对Oracle碌服务器体系结构和特性的玛了解程度。在试图调整你的赎系统前,你应熟悉Oracle赎调整的内容。 为瘤调整你已有的系统,遵从下瘤列步骤: 调整操手作系统的硬件和软件 田 通过查询V $SESSION_WAIT田视图,田识别性能的瓶颈,这个动态田性能视图列出了造成会话(session)您等待的事您件
10、。 通过分析V $SESSION_WAIT叁叁中的数据,决定瓶颈的叁原因。 纠正存在倪的问题。 监控应用系镶统 这主要是通过监控暮oracle的动态视图来暮完成。各种有用的动态视图暮:如v$session_wait, v$session_event暮暮等。 箩第2章 有效的应用设箩计 我们通常将最常用吩的应用分为2种类型:联机吩事务处理类型(OLTP)吩,决策支持系统(DSS)吩。 联机事务处理(O档LTP) 该类型的喘应用是高吞吐量,插入、更喘新、删除操作比较多的系统喘,这些系统以不断增长的大喘容量数据为特征,它们提供喘给成百用户同时存取,典型喘的OLTP系统 是订票系喘统,银行的业务系统,
11、订单脆系统。OTLP的主要目标脆是可用性、速度、并发性和脆可恢复性。当设计这类系统脆时,必须确保大量的并发用脆户不能干扰系统的 性能。脆还需要避免使用过量的索引脆与cluster 表,因脆为这些结构会使插入和更新脆操作变慢。 决策支持豹(DSS) 该类型豹的应用将大量信息进行提取豹形成报告,协助决策者作出碑正确的判断。典型的情况是井:决策支持系统将OLTP井应用收集的大量数据进行查井询。典型的应用为 客户行井为分析系统(超市,保险等井)。决策支持的关键目标是井速度、精确性和可用性。该井种类型的设计往往与OLTP井设计的理念背道而驰,一逞般建议使用数据冗 余、大逞量索引、cluster tabl
12、e逞、并行查询等。逞近年来,该类型的应用逐渐逞与OLAP、数据仓库紧密逞的联系在一起,形成的一个逞新的应用方向。第3章溅SQL语句处理的过程 确在调整之前我们需要了解确一些背景知识,只有知道这确些背景知识,我们才能更好确的去调整sql语句。 掠本节介绍了SQL语句处掠理的基本过程,主要包括:掠 查询语句处理睡 DML语句处谱理(insert, up谱date, delete谱) DDL 语蓬句处理(create .蓬. , drop .蓬, alter . ,蓬) 事务控制析(commit, rol析lback)SQL蒲语句的执行过程(SQL蒲Statement E蒲xecution)隐在某些
13、情况下,Oracl徐e运行sql的过程可能与徐下面列出的各个阶段的顺序徐有所不同。如DEFINE徐阶段可能在FETCH阶段徐之前,这主要依赖你如何书徐写代码。 对许多o再racle的工具来说,其再中某些阶段会自动执行。绝再大多数用户不需要关心各个再阶段的细节问题,然而,知贞道执行的各个阶段还是有必贞要的,这会帮助 你写出更贞高效的SQL语句来,而且贞还可以让你猜测出性能差的贞SQL语句主要是由于哪一贞个阶段造成的,然后我们针贞对这个具体的阶段,找出解贞决的办法。 DML语钝句的处理 本节给出一稿个例子来说明在DML语句稿处理的各个阶段到底发生了稿什么事情。假设你使用Pr稿o*C程序来为指定部门
14、的稿所有职员增加工资。程序已稿经连到正确的用户,你可以疆在你的程序中嵌入如下的S邦QL语句: EXEC S邦QL UPDATE em邦ployeesSET邦salary = 1.1船0 * salary W船HERE departm船ent_id = :va船r_department船_id;var_d船epartment_id船是程序变量,里面包含部门船号,我们要修改该部门的职船员的工资。当这个SQL语各句执行时,使用该变量的值各。 每种类型的语句都汛需要如下阶段: 愿 第1步: Create胰a Cursor创建胰游标 第2步:引Parse the S引tatement分析语引句 第5步:
15、袖Bind Any Var袖iables绑定变量袖 第7步: Ru颤n the Statem出ent运行语句 姐 第9步: Close姐the Cursor姐关闭游标 如果使用了碧并行功能,还会包含下面这碧个阶段: 第6然步: Paralleli然ze the State然ment并行执行语句然如果是查询语句,则需邱要以下几个额外的步骤,如邱图 3所示: 僳第3步: Describ僳e Results of僳a Query描述查僳询的结果集 第嵌4步: Define O嵌utput of a Q嵌uery定义查询的输出嵌数据 第8步:篱Fetch Rows篱of a Query取篱查询出来的行
16、 下面具甚体说一下每一步中都发生了甚什么事情:. 第1步题: 创建游标(Creat在e a Cursor)在 由程序接口调用创建帐一个游标(cursor)延。任何SQL语句都会创建延它,特别在运行DML语句延时,都是自动创建游标的,延不需要开发人员干预。多数延应用 中,游标的创建是自延动的。然而,在预编译程序延(pro*c)中游标的创穴建,可能是隐含的,也可能穴显式的创建。在存储过程中穴也是这样的。 第2步抑:分析语句(Parse允the Statemen允t)在语法分析期间在,SQL语句从用户进程传在送到Oracle,SQL隐语句经语法分析后,SQL隐语句本身与分析的信息都被隐装入到共享SQ
17、L区。在该隐阶段中,可以解决许多类型隐的错误。 语法分析分迂别执行下列操作: 丈翻译SQL语句,验证它是丈合法的语句,即书写正确丈实现数据字典的查找罐,以验证是否符合表和列的罐定义 在所要求的对堆象上获取语法分析锁,使得堆在语句的语法分析过程中不邦改变这些对象的定义 姑验证为存取所涉及的模式姑对象所需的权限是否满足桂决定此语句最佳的执咎行计划 将它装入共烩享SQL区 对分布呢的语句来说,把语句的全部呢或部分路由到包含所涉及数呢据的远程节点 以上任粮何一步出现错误,都将导致粮语句报错,中止执行。 翔只有在共享池中不存在等翔价SQL语句的情况下,才乔对SQL语句作语法分析。男在这种情况下,数据库内
18、核男重新为该语句分配新的共享男SQL区,并对语句进行语男法分析。进行语法分析需要男耗费较多的资源,所以要尽男量避免进行语法分析,这是男优化的技巧之一。 技语法分析阶段包含了不管此技语句将执行多少次,而只需技分析一次的处理要求。Or技acle只对每个SQL语技句翻译一次,在以后再次执技行该语句时,只要该语句喘还在共享SQL区中,就可喘以避免对该语句重新进行语喘法分析,也就是此时可以直喘接使用其对应的执行计划对喘数据进行存取。这主要是通喘过绑定变量(bind v喘ariable)实现的,喘也就是我们常说的共享SQ喘L,后面会给出共享SQL场的概念。 虽然语法分快析验证了SQL语句的正确快性, 但语
19、法分析只能识别达在SQL语句执行之前所能达发现的错误(如书写错误、达权限不足等)。因此,有些达错误通过语法分析是抓不到达的。例如,在数据转换中的达错误或 在数据中的错(如达企图在主键中插入重复的值达)以及死锁等均是只有在语达句执行阶段期间才能遇到和达报告的错误或情况。 坞查询语句的处理 查勿询与其它类型的SQL语句妹不同,因为在成功执行后作妹为结果将返回数据。其它语妹句只是简单地返回成功或失妹败,而查询则能返回一行或妹许多行数据。查询的结 果妹均采用表格形式,结果行被妹一次一行或者批量地被检索妹出来。从这里我们可以得知妹批量的fetch数据可以篱降低网络开销,所以批量的篱fetch也是优化的技
20、篱巧之一。 有些问题只皂与查询处理相关,查询不仅皂仅指SELECT语句,同皂样也包括在其它SQL语句皂中的隐含查询。例如,下面皂的每个语句都需要把查询作皂为它执行的一部分: IN皂SERT INTO ta皂ble SELECT.皂.UPDATE tab振le SET x = y振WHERE.DE振LETE FROM ta振ble WHERE.振CREATE tabl振e AS SELECT.振.具体来说,查询宙 要求读一致性彦 可能使用回滚段作裔中间处理 可能要唁求SQL语句处理描述、定唁义和取数据阶段 第3瞻步: 描述查询结果(De蛰scribe Resul蛰ts of a Quer蛰y)描
21、述阶段只有在截查询结果的各个列是未知时截才需要;例如,当查询由用溅户交互地输入需要输出的列溅名。在这种情况要用描述阶溅段来决定查询结果的特征(溅数据类型,长度和名字)。溅 第4步: 定义查询帮的输出数据(Define帮Output of a帮Query)在查镐询的定义阶段,你指定与查镐询出的列值对应的接收变量镐的位置、大小和数据类型,镐这样我们通过接收变量就可镐以得到查询结果。如果必要镐的话,Oracle会自动镐实现数据类型的转换。这是镐将接收变量的类型与对应的镐列类型相比较决定的。 曾第5步: 绑定变量(B曾ind Any Vari曾ables) 此时仪,Oracle知道了SQ仪L语句的意思
22、,但仍没有足仪够的信息用于执行该语句。仪Oracle 需要得到在仪语句中列出的所有变量的值仪。在该例中,Oracle责需要得到对departm责ent_id列进行限定的责值。得到这个值的过程就叫责绑定变量(bindin责g variables)责此过程称之为将变量玲值捆绑进来。程序必须指出玲可以找到该数值的变量名(玲该变量被称为捆绑 变量,玲变量名实质上是一个内存地玲址,相当于指针)。应用的玲最终用户可能并没有发觉他玲们正在指定捆绑变量,因为挝Oracle 的程序可能挝只是简单地指示他们输入新挝的值,其实这一切都在程序挝中自动做了。因为你指定了挝变量名,在你再次执行之前挝无须重新捆绑变量。你可
23、以挝改变绑定变量的 值,而O挝racle在每次执行时,挝仅仅使用内存地址来查找此且值。如果Oracle 需且要实现自动数据类型转换的且话(除非它们是隐含的或缺且省的),你还必须对每个值且指定数据类型和长度。关于且这些信息可以参考orac且le的相关文档,如Or且acle Call In且terface Prog且rammers Gui情de第6步: 并行麦执行语句(Paralle裸lize the Sta裸tement ) 戌ORACLE 可以在SE雁LECTs, INSER雁Ts, UPDATEs,雁MERGEs, DEL雁ETEs语句中执行相应并雁行查询操作,对于某些DD雁L操作,如创建索
24、引、用子雁查询创建表、在分区表上的雁操作,也可以执行并行操作折。并行化可以导致多 个服折务器进程(oracle折server proce折sses)为同一个SQL折语句工作,使该SQL语句折可以快速完成,但是会耗费折更多的资源,所以除非很有折必要,否则不要使用并行查折询。 第7步: 执行咬语句(Run the S咬tatement)妹到了现在这个时候,Or妹acle拥有所有需要的信妹息与资源,因此可以真正运妹行SQL语句了。如果该语鸟句为SELECT查询或I鸟NSERT语句,则不需要鸟 锁定任何行,因为没有数鸟据需要被改变。然而,如果鸟语句为UPDATE或DE鸟LETE语句,则该语句影鸟响的所
25、有行都被锁定,防止聂该用户提交或回滚之前,别聂的 用户对这些数据进行修聂改。这保证了数据的一致性聂。对于某些语句,你可以指聂定执行的次数,这称为批处聂理(array proc聂essing)。指定执行聂N次,则绑定变量与定义变聂量被定义为大小为N的数组赛的开始位置,这种方法可以赛减少网络开销,也是优化的赛技巧之一。 第8天步: 取出查询的行(Fe天tch Rows of天a Query)在天fetch阶段,行数据被坞取出来,每个后续的存取操坞作检索结果集中的下一行数镍据,直到最后一行被取出来镍。上面提到过,批量的fe镍tch是优化的技巧之一。镍 第9步: 关闭游标蓬(Close the C蓬u
26、rsor)SQL缮语句处理的最后一个阶段就缮是关闭游标 DDL语略句的处理(DDL Sta略tement Proce略ssing) DD置L语句的执行不同与DML置语句和查询语句的执行,这置是因为DDL语句执行成功置后需要对数据字典数据进行置修改。对于DDL语句,语许句的分析阶段实际上 包括许分析、查找数据字典信息和许执行。事务管理语句、会话许管理语句、系统管理语句只许有分析与执行阶段,为了重许新执行该语句,会重新分析许与执行该语句。 事务贮控制(Control o戌f Transactio戌ns) 一般来说,袖只有使用ORACLE编程袖接口的应用设计人员才关心袖操作的类型,并把相关的操袖作组
27、织在一起,形成一个事袖务。一般来说,我门必须定征义事务,这样 在一个逻辑征单元中的所有工作可以同时征被提交或回滚,保证了数据征的一致性。一个事务应该由征逻辑单元中的所有必须部分征组成,不应该多一个,也不征应该少一个。 在谊事务开始和结束的这段时间谊内,所有被引用表中的数据谊都应该在一致的状态(或可谊以被回溯到一致的状态)谊 事务应该只包含可斟以对数据进行一致更改(o斟ne consisten斟t change to椅the data)的SQ椅L语句 例如,在两执个帐号之间的转帐(这是一执个事务或逻辑工作单元),执应该包含从一个帐号中借钱执(由一个SQL完成),然执后将借的钱存入另一个帐号执(由
28、另一个 SQL完成)宙。这2个操作作为一个逻辑宙单元,应该同时成功或同时宙失败。其它不相关的操作,宙如向一个帐户中存钱,不应宙该包含在这个转帐事务中。宙 在设计应用时,除了扼需要决定哪种类型的操作组扼成一个事务外,还需要决定烩使用BEGIN_DISC烩RETE_TRANSAC烩TIO存储过程是否对提高烩小的、非分布式的事务的性烩能有作用。第4章OR此ACLE的优化器 优劫化器有时也被称为查询优化炽器,这是因为查询是影响数炽据库性能 最主要的部分,炽不要以为只有SELECT炽语句是查询。实际上,带有炽任何WHERE条件的DM炽L(INSERT、UPD炽ATE、DELETE)语贩句中都包含 查询要
29、求,在贩后面的文章中,当说到查询贩时,不一定只是指SELE贩CT语句,也有可能指DM贩L语句中的查询部分。优化贩器是所有关系数据库引擎中贩的最神秘、最 富挑战性的颁部件之一,从性能的角度看颁也是最重要的部分,它性能颁的高低直接关系到数据库性颁能的好坏。 我们知道构,SQL语句同其它语 言构(如C语言)的语句不一样警,它是非过程化(non-警procedural)的警语句,即当你要取数据时,警不需要告诉数据库通过何种警途径去取数据,如到底是警通过索引取数据,还是应该警将表中的每行数据都取出来警,然后再通过一一比较的方峻式取数据(即全表扫描),惭这是由数据库的优化器决定惭的,这就是非过程化的含惭义
30、,也就是说,如何取数据父是由优化器决定,而不是应父用开发者通过编程决定。在父处理SQL的SELECT父、UPDATE、INSE镐RT或DELETE语句镐时,Oracle 必须访镐问语句所涉及的数据,Or镐acle的优化器部分用来镐决定访问数据的有效路径,镐使得语句执行所需的I/O镐和处理时间最小。 揪为了实现一个查询,内核必揪须为每个查询定制一个查询揪策略,或为取出符合条件的揪数据生成一个执行计划(e揪xecution pla揪n)。典型的,对于同一个揪查询,可能有几个执行计划管都符合要求,都能得到符合管条件的数据。例如,参与连管接的表可以有多种不同的连管接方法,这取决于连 接条管件和优化器采
31、用的连接方法管。为了在多个执行计划中选管择最优的执行计划,优化器管必须使用一些实际的指标来管衡量每个执行计划使用的资秆源(I/0次数、CPU秆等),这些资源也就是我们秆所说的代价(cost)。秆如果一个执行计划使用的资秆源多,我们就说使用执行计秆划的代价大。以执行计划的秆代价大小作为衡量标 准,秆优化器选择代价最小的执行嘎计划作为真正执行该查询的管执行计划,并抛弃其它的执管行计划。 在ORAC局LE的发展过程中,一共开魂发过2种类型的优化器:基魂于规则的优化器和基于代价魂的优化器。这2种优化器的魂不同之处关键在于:取得代魂价的方法与衡量代价的大小魂不同。现对每种优化器做一魂下简单的介绍: 基于
32、替规则的优化器- Ru替le Based (He替uristic) Opt替imization(简称替RBO): 在OR屈ACLE7之前,主要是使屈用基于规则的优化器。OR屈ACLE在基于规则的优化屈器中采用启发式的方法(H屈euristic App屈roach)或规则(Ru屈les)来生成执行计划。屈例如,如果一个查询的wh屈ere条件(where屈clause)包含一个谓屈词(predicate,屈其实就是一个判断条件,如屈”=”, “”, ”束”等),而且该谓词上引用束的列上有有效索引,那么优束化器将使用索引访问这个表束,而不考虑其它因素,如表束中数据的多少、表中数据的束易变性、索引的
33、可选择性束等。此时数据库中没有关于涅表与索引数据的统计性描述涅,如表中有多上行,每行的涅可选择性等。优化器也不考涅虑实例参数,如multi蒲block i/o、可蒲用排序内存的大小等,所以蒲优化器有时就选择了次优化蒲的计划作为真正的执行计划蒲,导致系统性能不高。 羌如,对于select陆* from emp陆where deptno陆= 10这个查询来说,陆如果是使用基于规则的优化陆器,而且deptno列上陆有有效的索引,则会通过d陆eptno列上的索引来访汉问emp表。在绝大多数情汉况下, 这是比较高效的,汉但是在一些特殊情况下,使汉用索引访问也有比较低效的汉时候,现举例说明: 珐1) em
34、p表比较小垦,该表的数据只存放在几个垦数据块中。此时使用全表扫垦描比使用索引访问emp表垦反而要好。因为表比较小,垦极有可能数据全在内存中,垦所以此时做 全表扫描是最垦快的。而如果使用索引扫描垦,需要先从索引中找到符合睹条件记录的rowid,然睹后再一一根据这些rowi睹d从emp中将数据取出来睹,在这种条件 下,效率就睹会比全表扫描的效率要差一睹些。 2) emp表瑚比较大时,而且deptn瑚o = 10条件能查询出瑚表中大部分的数据如(50瑚%)。如该表共有4000瑚万行数据,共放在有500瑚000个数据块中,每个数谗据块为8k,则该表共有约谗4G,则 这么多的数据不谗可能全放在内存中,绝
35、大多谗数需要放在硬盘上。此时如谗果该查询通过索引查询,则谗是你梦魇的开始。db_谗file_multibl谗ock_read_cou厨nt参数的值200。如果厨采用全表扫描,则需要5厨00000/db_fil厨e_multiblock厨_read_count=厨500000/200=2厨500次I/O。但是如果厨采用索引扫描,假设de厨ptno列上的索引都已经陆cache到内存中,所以陆可以将访问索引的开销忽略陆不计。因为要读出4000陆万x 50% = 200陆0万数据,假设在读这20陆00万数据时,有99.9陆%的命中率,则还是需要2陆0000次I/O,比上面嵌的全表扫描需要的2500嵌次
36、多多了,所以在这 种情嵌况下,用索引扫描反而性能嵌会差很多。在这样的情况下嵌,用全表扫描的时间是固定嵌的,但是用索引扫描的时间嵌会随着选出数据的增多使查嵌询时间相应的延长。 磷上面是枯燥的假设数据,现磷在以具体的实例给予验证:磷 环境: oracl抿e 817 + linu抿x +阵列柜,表SWD抿_BILLDETAIL有抿3200多万数据; 裸表的id列、cn列上都有裸索引 经查看执行计孽划,发现执行select孽count(id) f孽rom SWD_BILL孽DETAIL;使用全表扫敢描,执行完用了大约1.5敢0分钟(4次执行取平均,敢每次分别为1.45 1.敢51 2.00 1.46敢
37、)。而执行select敢count(id) fr敢om SWD_BILLD敢ETAIL where川却用了2川个小时还没有执行完,经分川析该语句使用了cn列上的川索引,然后利用查询出的r川owid再从表中查询数据川。我为什么不使用sel掉ect count(cn掉) from SWD_B掉ILLDETAIL wh掉掉呢?后面在分析执行路径的掉索引扫描时时会给出说明。掉 下面就是基于规则的斧优化器使用的执行路径与各斧个路径对应的等级: 梗RBO Path 1:梗Single Row b戒y Rowid(等级最高戒) RBO Path玖2: Single R汉ow by Cluste汉r Join
38、RBO城Path 3: Sin混gle Row by H混ash Cluster混Key with Uni混que or Prima混ry KeyRBO洲Path 4: Sin洲gle Row by U洲nique or Pri洲mary KeyR宇BO Path 5: C宇lustered Joi宇nRBO Path只6: Hash Clu只ster KeyR秀BO Path 7: I秀ndexed Clust秀er KeyRBO议Path 8: Com议posite Index议RBO Path贞9: Single-Co贞lumn Indexes贞RBO Path余10: Bounded余
39、Range Search延1对于需要访问盯跨节点(即通常说的服务器盯)数据库上数据的查询来说盯,存在network代价盯,用来量化传输操作耗费的盯资源。查询远程表的查询或盯执行分布式连接的查询会在盯network代价方面花盯费比较大。 在使用半CBO时,需要有表和索引半的统计数据(分析数据)作半为基础数据,有了这些数据半,CBO才能为各个执行计半划计算出相对准确的代价,半从而使CBO选择 最佳的罐执行计划。所以定期的对表罐、索引进行分析是绝对必要罐的,这样才能使统计数据反罐映数据库中的真实情况。否罐则就会使CBO选择较差的罐执行计划,影响数据 库的罐性能。分析操作不必做的太罐频繁,一般来说,每
40、星期一罐次就足够了。切记如果想使罐用CBO,则必须定期对表构和索引进行分析。 对浑于 分析用的命令,随着数浑据库版本的升级,用的命令浑也发生了变换,在orac浑le 8i以前,主要是用浑ANALYZE命令。在O浑RACLE 8I以后,又镐引入了DBMS_STAT镐S存储包来进行分析。幸运镐的是从ORACLE 10镐G以后,分析工作变成自动镐的了,这减轻的DBA的负镐担,不过在一些特殊情况下镐,还需要一些手工分析。版如果采用了CBO优化瀑 器,而没有对表和索引进窃行分析,没有统计数据,则窃ORACLE使用缺省的统窃计数据(至少在ORACL窃E 9I中是这样),这可窃以从oracle的文档上窃找到
41、。使用的缺省值肯定与窃系统的实际统计值不一致,窃这可能会导致优化器选择错窃误的执行计划,影响数据库茫的性 能。 要注意的缮是:虽然CBO的功能随着缮ORACLE新版本的推出缮,功能越来越强,但它不是缮能包治百病的神药,否则就缮不再需要 DBA了,那我缮就惨了!实际上任何一缮个语句,随着硬件环境与应赎用数据的不同,该语句的执赎行计划可能需要随之发生变赎化,这样才能取得最好的性赎能。所以有 时候不在具体赎的环境下而进行SQL性能赎调整是徒劳的。 在O篱RACLE8I推出的时候篱,ORACLE极力建议大篱家使用CBO,说CBO有梭种种好处,但是在那是OR梭ACLE开发的应用系统还梭是使用基于规则的优
42、化器,梭从这件事上我们可以得出这梭样的结论:1)识如果团队的数据库水平很高识而且都熟悉应用数据的特点舷,RBO也可以取得很好的舷性能。 2)CB萝O不是很稳定,但是一个比萝较有前途的优化器,Ora溶cle极力建议大家用是为溶了让大家尽快发现它的BU溶G,以便进一步改善,但是溶ORACLE为 了对自己辖开发的应用系统负责,他们辖还是使用了比较熟悉而且成辖熟的RBO。从这个事情上辖给我们的启发就是:我们在辖以后的开发中,应该尽量采辖用我们熟悉并且成 熟的技辖术,而不要一味的采用新技辖术,一味采用新技术并不一辖定能开发出好的产品。幸运示的是从ORACLE 10示G后,CBO已经足够的强示大与智能,大
43、家可以放心的示使用该技术,因为ORAC示LE 10G后,Orac示le自己开发的应用系统也示使用CBO优化器了。而且穗ORACLE规定,从OR穗ACLE 10G开始,开穗始废弃RBO优化器。这句穗话并不是指在ORACLE缮10G中不能使用RBO缮,而是从ORACLE 1缮0G开始开始,不再为RB瑞O的BUG提供修补服务。瑞 在上面的第2个例子虚中,如果采用CBO优化器韵,它就会考虑emp表的行韵 数,deptno列的统韵计数据,发现对该列做查询韵会查询出过多的数据,并且彰考虑db_file_mu彰ltiblock_rea彰d_count参数的设置彰, 发现用全表扫描的代价焉比用索引扫描的代价要
44、小,焉从而使用全表扫描从而取得焉良好的执行性能。 判迎断当前数据库使用何种优化迎器: 主要是由opt讶imizer_mode初讶始化参数决定的。该参数可讶能的取值为:first_咱rows_1 | 10咱| 100 | 100咱0 | first_r咱ows | all_ro咱ws | choose咱| rule。具体解释如咱下: RULE为使用兽RBO优化器。 CH辖OOSE则是根据实际情况辖,如果数据字典中包含被引辖用的表的统计数据,即引用辖的对象已经被分析,则就使辖用CBO优化器,否则为R容BO优化器。 ALL捎_ROWS为CBO优化器屯使用的第一种具体的优化方屯法,是以数据的吞吐量为主
45、屯要目标,以便可以使用最少屯的资源完成语句。 F怜IRST_ROWS为优化怜器使用的第二种具体的优化怜方法,是以数据的响应时间怜为主要目标,以便快速查询怜出开始的几行数据。 屈FIRST_ROWS_屈1 | 10 | 100屈| 1000为优化屈器使用的第三种具体的优化屈方法,让优化器选择一个能屈够把响应时间减到最小的查屈询执行计划,以迅速产生查粟询结果的前 n 行。该参粟数为ORACLE 9I新粟引入的。 从ORAC丸LE V7以来,opti丸mizer_mode参数往的缺省设置应是choo洲se,即如果对已分析的洲表查询的话选择CBO,否洲则选择RBO。在此种设置洲中,如果采用了CBO,则
46、洲缺省为CBO中的all_洲rows模式。 注绣意:即使指定数据库使用R绣BO优化器,但有时ORA绣CLE数据库还是会采用C绣BO优化器,这并不是OR绣ACLE的BUG,主要是致由于从ORACLE 8I致后引入的许多新特性都必须致在CBO下才能使用,而你致的SQL语句可能正好使用致了这些新特性,此时数据库致会自动转为使用CBO优化冤器执行这些语句。 什洲么是优化 优化是选搬择最有效的执行计划来执行搬SQL语句的过程,这是在搬处理任何数据的语句(SE搬LECT,INSERT,搬UPDATE或DELET搬E)中的一个重 要步骤。葛对Oracle来说,执行葛这样的语句有许多不同的方葛法,譬如说,将随
47、着以什么葛顺序访问哪些表或索引的不葛同而不同。所使用的执行计葛划可以决定语句能 执行得葛有多快。Oracle中称葛之为优化器(Optimi釜zer)的组件用来选择这釜种它认为最有效的执行计划釜。 由于一系列因素都粉 会会影响语句的执行,优粉化器综合权衡各个因素,在粉众多的执行计划中选择认为办是最佳的执行计划。然而,办应用设计人员通常比优化器惭更知道关于特定应用的数据惭特 点。无论优化器多么智惭能,在某些情况下开发人员惭能选择出比优化器选择的最躇优执行计划还要好的执行计躇划。这是需要人工干预数据躇库优化的主要原因。事实表躇明, 在某些情况下,确实躇需要DBA对某些语句进行贩手工优化。 注:从O骸
48、racle的一个版本到另骸一个版本,优化器可能对同绸一语句生成不同的执行计划绸。在将来的Oracle绸版本中,优化器可能会基于绸它可以用的更好、更理想的绸信息,作出更优的决策,从绸而导致为语句产生更优的执荤行计划。第5章ORA才CLE的执行计划 背丸景知识: 为了更好的吗进行下面的内容我们必须了吗解一些概念性的术语: 抑共享sql语句 榨为了不重复解析相同的SQ榨L语句(因为解析操作比较需费资源,会导致性能下降)需,在第一次解析之后,OR需ACLE将SQL语句及解需析后得到的执行计划存放需在内存中。这块位于系统全需局区域SGA(syste嗅m global are嗅a)的共享池(share嗅d
49、 buffer poo嗅l)中的内存可以被所有的嗅数据库用户共享。因此,当嗅你执行一个SQL语句(有嗅时被称为一个游标)时,如嗅果该语句和之前的执行过的吟某一语句完全相同, 并且吟之前执行的该语句与其执行吟计划仍然在内存中存在,则吟ORACLE就不需要再进吟行分析,直接得到该语句的吟执行路径。ORACLE的吟这个功能大大地提高了S吟QL的执行性能并大大节省阵了内存的使用。使用这个功阵能的关键是将执行过的语句阵尽可能放到内存中,所以这阵要求有大的共享池(通过设阵置shared buff阵er pool参数值)和阵尽可能的使用绑定变量的方阵法执行SQL语句。 症当你向ORACLE 提交之一个SQL
50、语句,ORAC延LE会首先在共享内存中查延找是否有相同的语句。这里延需要注明的是,ORACL延E对两者采取的是一种严格延匹配,要达成共享,SQL延语句必须完全相同(包括空迎格,换行等)。 下面元是判断SQL语句是否与共元享内存中某一SQL相同的元步骤: 1) 对所发裔出语句的文本串进行has裔hed。如果hash值与裔已在共享池中SQL语句的预hash值相同,则进行第预2步;2) 将所绘发出语句的文本串(包括大绘小写、空白和注释)与在第绘步中识别的所有已存在的绘SQL语句相比较。 鲍例如: SELECT *鲍FROM emp WH档ERE empno =档1000;和下列每兵一个都不同 SEL
51、ECT兵* from emp兵WHERE empno兵= 1000;SELE兵CT * FROM EM兵P WHERE empn档o = 1000;SE档LECT * FROM档emp WHERE em档pno = 2000;档在上面的语句中列值都绚是直接SQL语句中的,今绚后我们将这类sql成为硬溅编码SQL或字面值SQL溅使用绑定变量的SQ夹L语句中必须使用相同的名夹字的绑定变量(bind杆variables),杆 例如: a.控该2个sql语句被认为相瓣同 select pin瓣, name from瓣people wher瓣e pin = :blk瓣1.pin;selec瓣t pin
52、, name瓣from people瓣where pin =秆:blk1.pin;秆b. 该2个sql语木句被认为不相同 sele榴ct pin , nam榴e from peopl榴e where pin榴= :blk1.ot_i榴nd;select p榴in , name fr榴om people wh榴ere pin = :b榴lk1.ov_ind;飘今后我们将上面的这类髓语句称为绑定变量SQL。髓 3) 将所发出语句卧中涉及的对象与第步中识卧别的已存在语句所涉及对象卧相比较。 例如: 朋如用户user1与用户浦user2下都有EMP表浦,则用户user1发出的浦语句:SELECT *浦
53、FROM EMP;与浦用户user2发出的语句立:SELECT * FR立OM EMP;被认为是立不相同的语句,因为两个语立句中引用的EMP不是指同细一个表。 4) 在S选QL语句中使用的捆绑变量选的捆绑类型必须一致。 焉如果语句与当前在共享池焉中的另一个语句是等同的话焉,Oracle并不对它进焉行语法分析。而直接执行该焉语句,提高了执行效率,因焉为语法分析比较耗费资源。欲 注意的是,从ora较cle 8i开始,新引入睹了一个CURSOR_SH睹ARING参数,该参数的睹主要目的就是为了解决在编睹程过程中已大量使用的硬编睹码SQL问题。因为在实际睹开发中,很多程序人员为了睹提高开发速度,而采用
54、类似睹下面的开发方法: str褐_sql string;褐int_empno i褐nt;int_empn稿o = 2000;st稿r_sql = SEL稿ECT * FROM e稿mp WHERE emp稿no = + int稿_empno;斥 int_empno =斥1000;str_s斥ql = SELECT斥* FROM emp斥WHERE empno承= + int_em倦pno; 上面的代绸码实际上使用了硬编码SQ绸L,使我们不能使用共享S绸QL的功能,结果是数据库绸效率不高。但是从上面的2郝个语句来看,产生的硬编码郝SQL只是列值 不同,其郝它部分都是相同的,如果仅郝仅因为列值不同
55、而导致这2郝个语句不能共享是很可惜的郝,为了解决这个问题,引入郝了CURSOR_SHAR灯ING参数,使这 类问题灯也可以使用共享SQL,从灯而使这样的开发也可以利用灯共享SQL功能。听起来不灯错,ORACLE真为用户灯着想,使用户在不改变代码灯的情况下还可以利用 共享寂SQL的功能。真的如此吗杆?天上不会无缘无故的掉一杆个馅饼的,ORACLE对杆该参数的使用做了说明,建杆议在经过实际测试后再改该杆参数的值(缺省情况 下,杆该参数的值为EXACT,杆语句完全一致才使用共享S磕QL)。因为有可能该变该磕值后,你的硬编码SQL是磕可以使用共享SQL了,但磕数据库的性能反而会下 降磕。 我在实际应用
56、中已经遇磕到这种情况。所以建议编写磕需要稳定运行程序的开发人磕员最好还是一开始就使用绑瑚定变量的SQL。 R哄owid的概念: 猫rowid是一个伪列,既识然是伪列,那么这个列就不识是用户定义,而是系统自己识给加上的。对每个表都有一识个rowid的伪列,但是识表中并不物理存储ROW识ID列的值。不过你可以像识使用其它列那样使用它,但识是不能删除改列,也不能对怂该列的值进行修改、插入。怂一旦一行数据插入数据库,怂则rowid在该行 的生怂命周期内是唯一的,即即使怂该行产生行迁移,行的ro怂wid也不会改变。 勿为什么使用ROWID 排 rowid对访问一个排表中的给定的行提供了最快排的访问方法,
57、通过ROWI排D可以直接定位到相应的数构据块上,然后将其读到内存构。我们创建一个索引时,该构索 引不但存储索引列的值构,而且也存储索引值所对应构的行的ROWID,这样我构们通过索引快速找到相应行构的ROWID后,通过该R构OWID,就可以迅速将数构据查 询出来。这也就是我碴们使用索引查询时,速度比碴较快的原因。 在OR讹ACLE8以前的版本中,讹ROWID由FILE 、讹BLOCK、ROW NU董MBER构成。随着ora般cle8中对象概念的扩展般,ROWID发生了变化,般ROWID由OBJECT般、FILE、BLOCK、般ROW NUMBER构成般。利用DBMS_ROWI警D可以将rowid
58、分解成警上述的各部分,也可以将上警述的各部分组成一个有效的警rowid。 Rec盯ursive SQL概念盯 有时为了执行用户缮发出的一个sql语句,O慕racle必须执行一些额慕外的语句,我们将这些额外慕的语句称之为recur慕sive calls或慕recursive S慕QL statement慕s。如当一个DDL语句譬发出后,ORACLE总是譬隐含的发出一些recur譬sive SQL语句,来譬修改数据字典信息,以便用譬户可以成功的执行该DDL譬语句。当需要的数据字典信譬息没有在共享内存中时,经欧常会发生Recursiv欧e calls,这些Re欧cursive call欧s会将数据字
59、典信息从硬盘欧读入内存中。用户不比关心欧这些recursive欧SQL语句的执行情况,在欧需要的时候,ORACLE路会自动的在内部执行这些语路句。当然DML语句与SE路LECT都可能引起rec路ursive SQL。简路单的说,我们可以将触发器路视为recursive路SQL。 Row S铆ource(行源) 言用在查询中,由上一操作返言回的符合条件的行的集合,言即可以是表的全部行数据的言集合;也可以是表的部分行言数据的集合;也可以为对上允2个row source允进行连接操作(如join允连接)后得到的行数据集合鱼。 Predicat延e(谓词) 一个查询仪中的WHERE限制条件仪Drivi
60、ng Ta徐ble(驱动表) 焉该表又称为外层表(OUT焉ER TABLE)。这个焉概念用于嵌套与HASH连逊接中。如果该row so逊urce返回较多的行数据逊,则对所有的后续操作有负逊面影响。注意此处虽然翻译逊为驱动表,但实际上翻译为逊驱动行源(driving颁row source)颁更为确切。一般说来,是应颁用查询的限制条件后,返回颁较少行源的表作为驱动表,颁所以如果一个大表在WHE掉RE条件有有限制条件(如掉等值限 制),则该大表作掉为驱动表也是合适的,所以掉并不是只有较小的表可以作掉为驱动表,正确说法应该为掉应用查询的限制条件后,返掉回较少行源的表作为驱动表掉。在执行 计划中,应该为
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 云南省玉溪市2025-2026学年八年级上学期期末考试信息技术 试题(解析版)
- 2026年及未来5年市场数据中国果汁饮料行业发展前景预测及投资方向研究报告
- 养老院环境卫生与消毒管理制度
- 企业薪酬福利管理制度
- 2026河南安阳新东投资集团有限公司招聘11人参考题库附答案
- 临保食品安全管理制度
- 2026湖北省定向中国政法大学选调生招录考试备考题库附答案
- 2026湖南株洲市第三中学面向高校毕业生招聘教师参考题库附答案
- 2026甘肃兰州海关技术中心酒泉实验室招聘非在编人员2人参考题库附答案
- 2026福建福州市残疾人联合会招聘1人参考题库附答案
- 房屋租赁合同txt
- 加工中心点检表
- 水库清淤工程可行性研究报告
- THBFIA 0004-2020 红枣制品标准
- GB/T 25630-2010透平压缩机性能试验规程
- GB/T 19610-2004卷烟通风的测定定义和测量原理
- 精排版《化工原理》讲稿(全)
- 中层管理干部领导力提升课件
- 市场营销学-第12章-服务市场营销课件
- 小微型客车租赁经营备案表
- 风生水起博主的投资周记
评论
0/150
提交评论