原文地址:http://blog.csdn.net/tianlesoftware/article/details/7008801
之前的blog中零零散散的整理了一些优化相关的内容,找起来比较麻烦,所以总结一下,查看的时候方便一点。这篇BLog只看SQL 优化的相关的注意事项,数据库优化部分以后有空在整理。
SQL 的优化主要涉及几个方面:
(1) 相关的统计信息缺失或者不准确
(2) 索引问题
(3) SQL 的本身的效率问题,比如使用绑定变量,批量DML 采用bulk等,这个就考验写SQL的基本功了,这一点也是最主要的一点。
一.SQL 编写注意事项
1.1 查看SQL
对于生产环境上的SQL,可以从AWR 或者 Statspack 报告中获取相关的SQL 信息。
这部分参考:
Oracle AWR 介绍
http://blog.csdn.net/tianlesoftware/article/details/4682300
statspack安装使用 和report 分析
http://blog.csdn.net/tianlesoftware/article/details/4682329
查看SQL 的性能怎么样,最直接的工具就是通过执行计划,通过执行计划可以看到SQL 的执行路径,逻辑读,物理读等信息,可以这些信息,可以帮助我们判断SQL 是否还有优化的余地。
1.2 SQL 编写的具体注意事项
这部分工作是基本功。 在SQL 编写过程中, 避免一些低效的写法,能将SQL的效率提高几倍。 如:
to_char(created,'yyyy') = '2011'
trunc(created,'y') = to_date('01-jan-2011','dd-mon-yyyy')
与使用TRUNC 相比,使用TO_CHAR 所用的CPU 时间与前者相差一个数量级(即相差12倍)。因为TO_CHAR 必须把日期转换为一个串,这要使用一个更大的代码路径,并利用当前的所有NLS来完成这个工作。然后必须执行一个串与串的比较。另一方面,TRUNC 只需把后5 个字节设置为1.然后将两个7 字节的二进制数进行比较。因此,如果只是要截断一个DATE 列,你将应该避免使用TO_CHAR。
之前从网上转载了一篇文章,链接如下:
Oracle SQL的优化
http://blog.csdn.net/tianlesoftware/article/details/4672023
这是几年前转载的文章,其中内容有些也有误,这里就不更正了。
1.3 多表关联方式
表之间的关联有如下三种方式:
(1) Nested Loop
Inner table 循环与outer table匹配,这种是表有索引,选择性较好,表之间的差距不大。 ===》两层for 循环,小表匹配大表。
(2) Hash John
小表做hash ,放内存,然后拿大表的每条记录做hash,然后与之前小表的Hash 值匹配。==》大表匹配小表。
(3) Sorted Merge Into
表有序,并且没有索引。
具体参考:
多表连接的三种方式详解 HASH JOIN MERGE JOINNESTED LOOP
http://blog.csdn.net/tianlesoftware/article/details/5826546
二. 相关理论说明
2.1 Oracle 优化器:CBO 和 RBO
Oracle 的优化器有两种:
RBO(Rule-BasedOptimization): 基于规则的优化器
CBO(Cost-BasedOptimization): 基于代价的优化器
CBO(Cost Based Optimizer)的思路是让Oracle 获取所有执行计划相关的信息,通过对这些信息做计算分析,最后得出一个代价最小的执行计划作为最终的执行计划。
从10g开始,Oracle 已经彻底丢弃了RBO。 即使在表,索引没有被分析的时候,Oracle依然会使用CBO。此时,Oracle 会使用一种叫做动态采样的技术,在分析SQL的时候,动态的收集表,索引上的一些数据块,使用这些数据块的信息及字典表中关于这些对象的信息来计算出执行计划的代价,从而挑出最优的执行计划。
当表没有做分析的时候,Oracle 会使用动态采样来收集统计信息,这个动作只有在SQL执行的第一次,即硬分析阶段使用,后续的软分析将不在使用动态采样,直接使用第一次SQL硬分析时生成的执行计划。
相关链接:
Oracle Optimizer CBO RBO
http://blog.csdn.net/tianlesoftware/article/details/5824886
Oracle CBO 与 RBO
http://blog.csdn.net/tianlesoftware/archive/2010/07/11/5709784.aspx
Oracle 分析及动态采样
http://blog.csdn.net/tianlesoftware/article/details/5845028
2.2 软解析和硬解析
Oracle对此SQL将进行几个步骤的处理过程:
1、语法检查(syntax check): 检查此sql的拼写是否语法。
2、语义检查(semantic check): 诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
3、对sql语句进行解析(prase): 利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。
4、执行sql,返回结果(execute and return)
其中解析分为:
Hard Parse: 就是上面提到的对提交的Sql完全重新从头进行解析(当在Shared Pool中找不到时候将会进行此操作),总共有一下5个执行步骤:
1:语法分析
2:权限与对象检查
3: 在共享池中检查是否有完全相同的之前完全解析好的. 如果存在,直接跳过4和5,运行Sql, 此时算soft parse.
4:选择执行计划
5:产生执行计划
注:创建解析树、生成执行计划对于sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。这就是在很多项目中,倡导开发设计人员对功能相同的代码要努力保持代码的一致性,以及要在程序中多使用绑定变量的原因。
Soft Parse: 就如果是在Shared Pool中找到了与之完全相同的Sql解析好的结果后会跳过Hard Parse中的后面的两个步骤。
Oracle SQL的硬解析和软解析
http://blog.csdn.net/tianlesoftware/archive/2010/04/08/5458896.aspx
Oracle 高 Version counts 问题说明
http://blog.csdn.net/tianlesoftware/article/details/6628232
Oracle SQL Parsing FlowDiagram(SQL 解析流程图)
http://blog.csdn.net/tianlesoftware/article/details/6625683
那么执行计划放在内存的什么位置,在一下的Blog 有说明:
Oracle Library cache 内部机制 说明
http://blog.csdn.net/tianlesoftware/article/details/6629869
与解析相关的一个重要参数:cursor_sharing,它决定什么情况下使用相同的cursor,从某种意义上讲,决定是否需要进行解析,该参数有3个值:
(1)FORCE
Allowsthe creation of a new cursor if sharing an existing cursor, or if the cursorplan is not optimal.
(2)SIMILAR
Causesstatements that may differ in some literals, but are otherwise identical, toshare a cursor, unless the literals affect either the meaning of the statementor the degree to which the plan is optimized.
(3)EXACT
Onlyallows statements with identical text to share the same cursor.
--只有SQL 语句完全相同的情况下,才会使用相同的cursor,即执行计划。
Oracle cursor_sharing 参数 详解
http://blog.csdn.net/tianlesoftware/article/details/6551723
2.3 执行计划
生成SQL的执行计划是Oracle在对SQL做硬解析时的一个非常重要的步骤,它制定出一个方案告诉Oracle在执行这条SQL时以什么样的方式访问数据:索引还是全表扫描,是Hash Join还是Nested loops Join等。
Oracle 执行计划(Explain Plan) 说明
http://blog.csdn.net/tianlesoftware/article/details/5827245
Oracle 从缓存里面查找真实的执行计划
http://blog.csdn.net/tianlesoftware/article/details/6556850
Oracle Recursive Calls 说明
http://blog.csdn.net/tianlesoftware/article/details/6561620
我们也可以使用OracleHint 来强制的改变SQL的执行计划,当然Oracle 不建议这么做,因为只要统计信息正确的情况下,CBO 的分析就过一般都是正确的。
Oracle Hint
http://blog.csdn.net/tianlesoftware/article/details/5833020
2.4 10053 和 10046 事件
2.4.1 10053事件
我们在查看一条SQL的执行计划的时候,只能看到CBO 最终告诉我们的执行计划结果,但是不知道CBO 是根据什么来做的。 如果遇到了执行计划失真,如:一个SQL语句,很明显oracle应该使用索引,但是执行计划却没有使用索引。无法进行分析判断。
10053事件就提供了这样的功能。它产生的trace文件提供了Oracle如何选择执行计划,为什么会得到这样的执行计划信息。
对于10053事件的trace文件,我们只能直接阅读原始的trace文件,不能使用tkprof工具来处理,tkprof工具只能用来处理sql_trace 和 10046事件产生的trace文件。
10053事件有两个级别:
Level2:2级是1级的一个子集,它包含以下内容:
Column statistics
Single Access Paths
Join Costs
Table Joins Considered
Join Methods Considered (NL/MS/HA)
Level1: 1级比2级更详细,它包含2级的所有内容,在加如下内容:
Parameters used by the optimizer
Index statistics
启用10053事件:
ALTER SESSION SET EVENTS='10053 trace namecontext forever, level 1';
ALTER SESSION SET EVENTS='10053 trace namecontext forever, level 2';
关闭10053事件:
ALTER SESSION SET EVENTS '10053 trace namecontext off';
说明:
(1)sqlplus中打开autotrace看到的执行计划实际上是用explain plan 命令得到的,explain plan 命令不会进行bind peeking。应该通过v$sql_plan查看SQL的真实的执行计划。
(2)10053只对CBO有效,而且如果一个sql语句已经解析过,就不会产生新的trace信息。
2.4.2 10046 事件:
10046 事件主要用来跟踪SQL语句,它并不是ORACLE 官方提供给用户的命令,在官方文档上也找不到事件的说明信息。 但是用的却比较多,因为10046事件获取SQL的信息比SQL_TRACE 更多。 更有利于我们对SQL的判断。
10046 事件按照收集信息内容,可以分成4个级别:
Level 1: 等同于SQL_TRACE 的功能
Level 4: 在Level 1的基础上增加收集绑定变量的信息
Level 8: 在Level 1 的基础上增加等待事件的信息
Level 12:等同于Level 4+Level 8, 即同时收集绑定变量信息和等待事件信息。
--启动10046事件
SQL>alter session set events‘10046 tracename context forever, level 12’;
-- 关闭10046事件
SQL>alter session set events ‘10046 trace name context off’;
也可以使用oradebug 命令来执行10046:
SYS@anqing1(rac1)> oradebug setmypid
SYS@anqing1(rac1)> oradebug event 10046trace name context forever,level 8;
SYS@anqing1(rac1)> oradebug event 10046trace name context off;
SYS@anqing1(rac1)> oradebugtracefile_name
/u01/app/oracle/admin/anqing/udump/anqing1_ora_17800.trc
具体的内容参考:
Oracle oradebug 命令 使用说明
http://blog.csdn.net/tianlesoftware/article/details/6525628
Oracle 跟踪事件 set event
http://blog.csdn.net/tianlesoftware/article/details/4977827
Oracle 10053 事件
http://blog.csdn.net/tianlesoftware/article/details/5859027
Event 10053 执行计划绑定变量 Bind peeking
http://blog.csdn.net/tianlesoftware/article/details/5544307
Oracle SQL Trace 和 10046 事件
http://blog.csdn.net/tianlesoftware/article/details/5857023
使用 Tkprof 分析 ORACLE 跟踪文件
http://blog.csdn.net/tianlesoftware/article/details/5632003
2.5 统计信息
优化器收集的统计信息包括如下内容:
1)Table statistics
Number of rows
Number of blocks
Average row length
2)Column statistics
Number of distinctvalues (NDV) in column
Number of nulls incolumn
Data distribution(histogram)
3)Index statistics
Number of leaf blocks
Levels
Clustering factor
4)System statistics
I/O performance and utilization
CPU performance andutilization
统计信息收集如下数据:
(1)表自身的分析: 包括表中的行数,数据块数,行长等信息。
(2)列的分析:包括列值的重复数,列上的空值,数据在列上的分布情况。
(3)索引的分析: 包括索引叶块的数量,索引的深度,索引的聚合因子等。
这些统计信息存放在数据字典里,如:
(1). DBA_TABLES
(2). DBA_OBJECT_TABLES
(3). DBA_TAB_STATISTICS
(4). DBA_TAB_COL_STATISTICS
(5). DBA_TAB_HISTOGRAMS
(6). DBA_INDEXES
(7). DBA_IND_STATISTICS
(8). DBA_CLUSTERS
(9). DBA_TAB_PARTITIONS
(10).DBA_TAB_SUBPARTITIONS
(11).DBA_IND_PARTITIONS
(12).DBA_IND_SUBPARTITIONS
(13).DBA_PART_COL_STATISTICS
(14).DBA_PART_HISTOGRAMS
(15).DBA_SUBPART_COL_STATISTICS
(16).DBA_SUBPART_HISTOGRAMS
统计信息的准确程度,直接决定SQL的效率。 所以需要定期的收集相关对象的统计信息。Oracle 的Statistic 信息的收集分两种:自动收集和手工收集。
Oracle 的Automatic StatisticsGathering 是通过Scheduler 来实现收集和维护的。 Job 名称是GATHER_STATS_JOB, 该Job收集数据库所有对象的2种统计信息:
(1)Missing statistics(统计信息缺失)
(2)Stale statistics(统计信息陈旧)
该Job 是在数据库创建的时候自动创建,并由Scheduler来管理。Scheduler 在maintenance windows open时运行gather job。 默认情况下,job 会在每天晚上10到早上6点和周末全天开启。该过程首先检测统计信息缺失和陈旧的对象。然后确定优先级,再开始进行统计信息。
Scheduler Job的 stop_on_window_close 属性控制GATHER_STATS_JOB 是否继续。该属性默认值为True. 如果该值设置为False,那么GATHER_STATS_JOB 会中断,而没有收集完的对象将在下次启动时继续收集。
Gather_stats_job 调用dbms_stats.gather_database_stats_job_proc过程来收集statistics 的信息。 该过程收集对象statistics的条件如下:
(1)对象的统计信息之前没有收集过。
(2)当对象有超过10%的rows 被修改,此时对象的统计信息也称为stale statistics。
Oracle Statistic 统计信息 小结
http://blog.csdn.net/tianlesoftware/article/details/4668723
Oracle 判断 并 手动收集 统计信息 脚本
http://blog.csdn.net/tianlesoftware/article/details/6445868
三.索引
3.1 索引分类
索引对DB的性能中起着重要的作用。 Oracle 有如下类型的索引:
B树索引(默认类型)
位图索引
HASH索引
索引组织表索引
反转键(reverse key)索引
基于函数的索引
分区索引(本地和全局索引)
位图连接索引
3.2 索引限制
这部分内容应该放到SQL 编写部分,不过为了强调,还是放到这块。
即使相关字段上有索引,在如下4种情况,也不会走作引:
(1) 使用不等于操作符(<>、!=)
(2) 使用IS NULL 或IS NOT NULL
(3) 使用函数
(4) 比较不匹配的数据类型
所以在SQL 编写过程中,尽量避免以上4种情况。
具体参考:
Oracle 索引详解
http://blog.csdn.net/tianlesoftware/article/details/5347098
3.3 索引维护
这部分内容包括:
(1) 索引的选择性: distinct/rows, 接近与1,选择性越高,直方图--》数据倾斜。
(2) 索引的扩展:index segment 是由extents组成,如果extents大于10,可以考虑重建索引。
(3) 索引碎片:查询index_stats表以确定索引中删除的、未填满的叶子(Leaf)行的百分比 和 height 字段。 如果索引的叶子行的碎片超过10%,或者 index_stats中height > =4, 可以考虑对索引进行重建。
select name,height, del_lf_rows, lf_rows,round((del_lf_rows/(lf_rows+0.0000000001))*100) "Frag Percent" from index_stats
具体参考:
索引维护:
http://blog.csdn.net/tianlesoftware/article/details/5680706
3.4 索引的 Clustering Factor 参数
这个参数是个神奇的参数,先看一种情况,有的人应该遇到过,就是表的字段上有索引,但根据这个字段做查询时,却发现Oracle并没有使用索引? 并且查询条件没有限制索引。那么Oracle 为什么不走索引? 很可能就是和这个参数值有关。
可以从dba_indexes 表里查看到每个具体对象的Clustering Factor值:
select owner,index_name, clustering_factor, num_rows from dba_indexes whereowner='SYS' and index_name='IDX_T_ID';
该参数反应的是数据在物理block的上的连续性,如果该值接近于对象的block数,那么数据在block上的存储就是有序的,如果接近与表的行数,可以反应出数据的存储无序。
当数据有序时,我们查询一个数据时,可以从一个block里一次性读出,如果无序,那么我们可能就需要读取多个block,这样I/O次数增加,CBO 就会认为这种代价更大,从而选择全表扫描来代替索引。从而导致即使有索引,也不会走。
但是随着系统使用时间的越长,Clustering Factor值是会越来越大的。解决这个问题的唯一方法就是对表进行move。
具体参考:
Oracle Index Clustering Factor 说明
http://blog.csdn.net/tianlesoftware/article/details/6585453
3.5 索引扫描5种类型:
(1)index unique scan: 查询结果返回一行记录
(2)index range scan: 查询结果返回多行记录。
(3)index full scan:可能进行全Oracle索引扫描而不是范围扫描,需要注意的是全Oracle索引扫描只在CBO模式下才有效。 CBO根据统计数值得知进行全Oracle索引扫描比进行全表扫描更有效时,才进行全Oracle索引扫描,而且此时查询出的数据都必须从索引中可以直接得到。
(4)index fast full scan: 与 index full scan很类似,但是一个显著的区别就是它不对查询出的数据进行排序,即数据不是以排序顺序被返回。在这种存取方法中,可以使用多块读功能,也可以使用并行读入,以便获得最大吞吐量与缩短执行时间。
(5)index skip scan: INDEX SKIP SCAN,发生在多个列建立的复合索引上,如果SQL中谓词条件只包含索引中的部分列,并且这些列不是建立索引时的第一列时,就可能发生INDEX SKIP SCAN。这里SKIP的意思是因为查询条件没有第一列或前面几列,被忽略了。
具体参考:
Oracle 索引扫描的五种类型
http://blog.csdn.net/tianlesoftware/article/details/5852106
四.绑定变量
这个也是SQL 编写的基本功. 简单的说,使用绑定变量可以避免进行硬解析,减少对资源的消耗。
Oracle里的所有SQL 语句都是implicitly sharable的。 SQL 在执行之前,要通过一个hash 运算,生成相关的cursor。 如果通过hash 运算之后,发现已经了有对应的cursor,那就可以直接使用之前的cursor 和plan。如果不存在,就需要进行硬解析,而硬解析是一个非常耗资源的操作。需要尽量减少硬解析。
如何保证每次HASH 运算之后的hash 值都一样,那么这就需要通过绑定变来来实现。
在第一次执行执行SQL 之后,如果使用了绑定变量,那么Oracle 在硬解析的时候,会进行一个叫Peek的操作。 也可以称为偷窥。就是把实际值带进去,帮助产生更加准确的执行计划。比如对应的Peek列上有严重的数据倾斜,假设我们已经对表进行了统计信息收集,oracle 会产生该列的直方图(histogram),在peek的时候,就会根据直方图来决定,是走索引还是走全表扫描更划算。
因此第一执行产生的执行计划肯定是最优的。现在假设数据倾斜有2个值,一个占90%,一个占10%。 我们第一使用10%的值,所以第一次走索引。 那么如果我们以后在绑定时,使用了90%的值,那么这时候,Oracle 还是会使用之前的cursor,继续走索引,此时走索引就不是最优的了。
这个就是Oracle 10g里绑定变量的一个问题。 在第一次硬解析之后,以后所有的操作都会使用之前产生的cursor 和plan。所以在10g里,对于列上有严重数据倾斜的,最好是不采用绑定变量。
在Oracle 11g里,对这个问题,进行了优化,使用了Adaptive Cursor Sharing,它可以产生多个共享cursor。如果是90%的值,就使用cursor 1,如果是10%的cursor,就使用corsor 2. 在这个转换的过程中还是有可能再次产生硬解析。
Oracle 11g的绑定变量处理过程如下:
当我们第一去执行一个带有绑定变量的SQL时,Oracle 会进行硬解析,但是硬解析不能确定最优的执行计划,所以这时候有了Peek。 也可以说是偷窥,即把实际值带入,来生成一个selectivity estimate。 然后来选择最优的一个执行计划来执行。
这是第一次执行SQL语句。以后执行时就会使用已经存在的plan和cursor。 Oracle 通过Adaptive Cursor Sharing特性允许同一个SQL 可以使用多个执行计划。
在每次执行时,Oracle会根据Peek 的selectivity estimate 值和直方图(如果存在)来判断已经存在的cursor 是否是最优的,如果不是,就重新创建一个child cursor,并讲Bind-Sensitive 标记为Y。
而且Oracle在SQL 每次执行时,都会收集相关的统计信息,然后根据统计信息进行判断,如果比上次的更好,就在创建一个child cursor,并将Bind-Aware 标记为Y。
当标记为bind-aware cursor 的cursor在下次执行时,Oracle根据新的bind value 来生成新的plan和cursor,并将原来的cursor标记为非共享,即V$SQL.IS_SHAREABLE 设置为 N,当这种cursor 长期不被使用时, 就会被移出shared SQL area.
在bind-aware cursor创建新的cursor 之后,如果这个cursor 和之前某个存在的cursor一样,那么Oracle 会对他们进行合并。
如果在cache里不能找到bind-aware对应的plan,那么就会重新进行一次硬解析,来生成plan 和cursor,如果这个plan 以后被新的cursor 使用,那么Oracle 会将这2个cursor 进行合并。
Oracle 绑定变量 详解
http://blog.csdn.net/tianlesoftware/article/details/5856430
Oracle 绑定变量 示例
http://blog.csdn.net/tianlesoftware/article/details/6324243
Oracle 10g 与 11g 绑定变量(Bind Variable) 区别 说明
http://blog.csdn.net/tianlesoftware/article/details/6591222
对于绑定变量的cursor 能否重用,与Cursor_sharing 参数有很大关系。具体参考:
Oracle cursor_sharing 参数 详解
http://blog.csdn.net/tianlesoftware/article/details/6551723
Oracle Library cache 内部机制 说明
http://blog.csdn.net/tianlesoftware/article/details/6629869
五.其他与SQL 性能相关的链接
Oracle Sequence Cache 参数说明
http://blog.csdn.net/tianlesoftware/article/details/5995051
Oracle bulk 示例
http://blog.csdn.net/tianlesoftware/article/details/6599003
Oracle Bulk 与 性能优化 说明
http://blog.csdn.net/tianlesoftware/article/details/6578351
Oracle Pipelined TableFunctions 与 性能优化 说明
http://blog.csdn.net/tianlesoftware/article/details/6601540
Oracle arraysize 和 fetchsize 参数 与 性能优化 说明
http://blog.csdn.net/tianlesoftware/article/details/6579913
Oracle 利用 rowid 提升 update 性能
http://blog.csdn.net/tianlesoftware/article/details/6576156
Oracle Parallel Execution(并行执行)
http://blog.csdn.net/tianlesoftware/article/details/5854583
之前的blog中零零散散的整理了一些优化相关的内容,找起来比较麻烦,所以总结一下,查看的时候方便一点。这篇BLog只看SQL 优化的相关的注意事项,数据库优化部分以后有空在整理。
SQL 的优化主要涉及几个方面:
(1) 相关的统计信息缺失或者不准确
(2) 索引问题
(3) SQL 的本身的效率问题,比如使用绑定变量,批量DML 采用bulk等,这个就考验写SQL的基本功了,这一点也是最主要的一点。
一.SQL 编写注意事项
1.1 查看SQL
对于生产环境上的SQL,可以从AWR 或者 Statspack 报告中获取相关的SQL 信息。
这部分参考:
Oracle AWR 介绍
http://blog.csdn.net/tianlesoftware/article/details/4682300
statspack安装使用 和report 分析
http://blog.csdn.net/tianlesoftware/article/details/4682329
查看SQL 的性能怎么样,最直接的工具就是通过执行计划,通过执行计划可以看到SQL 的执行路径,逻辑读,物理读等信息,可以这些信息,可以帮助我们判断SQL 是否还有优化的余地。
1.2 SQL 编写的具体注意事项
这部分工作是基本功。 在SQL 编写过程中, 避免一些低效的写法,能将SQL的效率提高几倍。 如:
to_char(created,'yyyy') = '2011'
trunc(created,'y') = to_date('01-jan-2011','dd-mon-yyyy')
与使用TRUNC 相比,使用TO_CHAR 所用的CPU 时间与前者相差一个数量级(即相差12倍)。因为TO_CHAR 必须把日期转换为一个串,这要使用一个更大的代码路径,并利用当前的所有NLS来完成这个工作。然后必须执行一个串与串的比较。另一方面,TRUNC 只需把后5 个字节设置为1.然后将两个7 字节的二进制数进行比较。因此,如果只是要截断一个DATE 列,你将应该避免使用TO_CHAR。
之前从网上转载了一篇文章,链接如下:
Oracle SQL的优化
http://blog.csdn.net/tianlesoftware/article/details/4672023
这是几年前转载的文章,其中内容有些也有误,这里就不更正了。
1.3 多表关联方式
表之间的关联有如下三种方式:
(1) Nested Loop
Inner table 循环与outer table匹配,这种是表有索引,选择性较好,表之间的差距不大。 ===》两层for 循环,小表匹配大表。
(2) Hash John
小表做hash ,放内存,然后拿大表的每条记录做hash,然后与之前小表的Hash 值匹配。==》大表匹配小表。
(3) Sorted Merge Into
表有序,并且没有索引。
具体参考:
多表连接的三种方式详解 HASH JOIN MERGE JOINNESTED LOOP
http://blog.csdn.net/tianlesoftware/article/details/5826546
二. 相关理论说明
2.1 Oracle 优化器:CBO 和 RBO
Oracle 的优化器有两种:
RBO(Rule-BasedOptimization): 基于规则的优化器
CBO(Cost-BasedOptimization): 基于代价的优化器
CBO(Cost Based Optimizer)的思路是让Oracle 获取所有执行计划相关的信息,通过对这些信息做计算分析,最后得出一个代价最小的执行计划作为最终的执行计划。
从10g开始,Oracle 已经彻底丢弃了RBO。 即使在表,索引没有被分析的时候,Oracle依然会使用CBO。此时,Oracle 会使用一种叫做动态采样的技术,在分析SQL的时候,动态的收集表,索引上的一些数据块,使用这些数据块的信息及字典表中关于这些对象的信息来计算出执行计划的代价,从而挑出最优的执行计划。
当表没有做分析的时候,Oracle 会使用动态采样来收集统计信息,这个动作只有在SQL执行的第一次,即硬分析阶段使用,后续的软分析将不在使用动态采样,直接使用第一次SQL硬分析时生成的执行计划。
相关链接:
Oracle Optimizer CBO RBO
http://blog.csdn.net/tianlesoftware/article/details/5824886
Oracle CBO 与 RBO
http://blog.csdn.net/tianlesoftware/archive/2010/07/11/5709784.aspx
Oracle 分析及动态采样
http://blog.csdn.net/tianlesoftware/article/details/5845028
2.2 软解析和硬解析
Oracle对此SQL将进行几个步骤的处理过程:
1、语法检查(syntax check): 检查此sql的拼写是否语法。
2、语义检查(semantic check): 诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
3、对sql语句进行解析(prase): 利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。
4、执行sql,返回结果(execute and return)
其中解析分为:
Hard Parse: 就是上面提到的对提交的Sql完全重新从头进行解析(当在Shared Pool中找不到时候将会进行此操作),总共有一下5个执行步骤:
1:语法分析
2:权限与对象检查
3: 在共享池中检查是否有完全相同的之前完全解析好的. 如果存在,直接跳过4和5,运行Sql, 此时算soft parse.
4:选择执行计划
5:产生执行计划
注:创建解析树、生成执行计划对于sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。这就是在很多项目中,倡导开发设计人员对功能相同的代码要努力保持代码的一致性,以及要在程序中多使用绑定变量的原因。
Soft Parse: 就如果是在Shared Pool中找到了与之完全相同的Sql解析好的结果后会跳过Hard Parse中的后面的两个步骤。
Oracle SQL的硬解析和软解析
http://blog.csdn.net/tianlesoftware/archive/2010/04/08/5458896.aspx
Oracle 高 Version counts 问题说明
http://blog.csdn.net/tianlesoftware/article/details/6628232
Oracle SQL Parsing FlowDiagram(SQL 解析流程图)
http://blog.csdn.net/tianlesoftware/article/details/6625683
那么执行计划放在内存的什么位置,在一下的Blog 有说明:
Oracle Library cache 内部机制 说明
http://blog.csdn.net/tianlesoftware/article/details/6629869
与解析相关的一个重要参数:cursor_sharing,它决定什么情况下使用相同的cursor,从某种意义上讲,决定是否需要进行解析,该参数有3个值:
(1)FORCE
Allowsthe creation of a new cursor if sharing an existing cursor, or if the cursorplan is not optimal.
(2)SIMILAR
Causesstatements that may differ in some literals, but are otherwise identical, toshare a cursor, unless the literals affect either the meaning of the statementor the degree to which the plan is optimized.
(3)EXACT
Onlyallows statements with identical text to share the same cursor.
--只有SQL 语句完全相同的情况下,才会使用相同的cursor,即执行计划。
Oracle cursor_sharing 参数 详解
http://blog.csdn.net/tianlesoftware/article/details/6551723
2.3 执行计划
生成SQL的执行计划是Oracle在对SQL做硬解析时的一个非常重要的步骤,它制定出一个方案告诉Oracle在执行这条SQL时以什么样的方式访问数据:索引还是全表扫描,是Hash Join还是Nested loops Join等。
Oracle 执行计划(Explain Plan) 说明
http://blog.csdn.net/tianlesoftware/article/details/5827245
Oracle 从缓存里面查找真实的执行计划
http://blog.csdn.net/tianlesoftware/article/details/6556850
Oracle Recursive Calls 说明
http://blog.csdn.net/tianlesoftware/article/details/6561620
我们也可以使用OracleHint 来强制的改变SQL的执行计划,当然Oracle 不建议这么做,因为只要统计信息正确的情况下,CBO 的分析就过一般都是正确的。
Oracle Hint
http://blog.csdn.net/tianlesoftware/article/details/5833020
2.4 10053 和 10046 事件
2.4.1 10053事件
我们在查看一条SQL的执行计划的时候,只能看到CBO 最终告诉我们的执行计划结果,但是不知道CBO 是根据什么来做的。 如果遇到了执行计划失真,如:一个SQL语句,很明显oracle应该使用索引,但是执行计划却没有使用索引。无法进行分析判断。
10053事件就提供了这样的功能。它产生的trace文件提供了Oracle如何选择执行计划,为什么会得到这样的执行计划信息。
对于10053事件的trace文件,我们只能直接阅读原始的trace文件,不能使用tkprof工具来处理,tkprof工具只能用来处理sql_trace 和 10046事件产生的trace文件。
10053事件有两个级别:
Level2:2级是1级的一个子集,它包含以下内容:
Column statistics
Single Access Paths
Join Costs
Table Joins Considered
Join Methods Considered (NL/MS/HA)
Level1: 1级比2级更详细,它包含2级的所有内容,在加如下内容:
Parameters used by the optimizer
Index statistics
启用10053事件:
ALTER SESSION SET EVENTS='10053 trace namecontext forever, level 1';
ALTER SESSION SET EVENTS='10053 trace namecontext forever, level 2';
关闭10053事件:
ALTER SESSION SET EVENTS '10053 trace namecontext off';
说明:
(1)sqlplus中打开autotrace看到的执行计划实际上是用explain plan 命令得到的,explain plan 命令不会进行bind peeking。应该通过v$sql_plan查看SQL的真实的执行计划。
(2)10053只对CBO有效,而且如果一个sql语句已经解析过,就不会产生新的trace信息。
2.4.2 10046 事件:
10046 事件主要用来跟踪SQL语句,它并不是ORACLE 官方提供给用户的命令,在官方文档上也找不到事件的说明信息。 但是用的却比较多,因为10046事件获取SQL的信息比SQL_TRACE 更多。 更有利于我们对SQL的判断。
10046 事件按照收集信息内容,可以分成4个级别:
Level 1: 等同于SQL_TRACE 的功能
Level 4: 在Level 1的基础上增加收集绑定变量的信息
Level 8: 在Level 1 的基础上增加等待事件的信息
Level 12:等同于Level 4+Level 8, 即同时收集绑定变量信息和等待事件信息。
--启动10046事件
SQL>alter session set events‘10046 tracename context forever, level 12’;
-- 关闭10046事件
SQL>alter session set events ‘10046 trace name context off’;
也可以使用oradebug 命令来执行10046:
SYS@anqing1(rac1)> oradebug setmypid
SYS@anqing1(rac1)> oradebug event 10046trace name context forever,level 8;
SYS@anqing1(rac1)> oradebug event 10046trace name context off;
SYS@anqing1(rac1)> oradebugtracefile_name
/u01/app/oracle/admin/anqing/udump/anqing1_ora_17800.trc
具体的内容参考:
Oracle oradebug 命令 使用说明
http://blog.csdn.net/tianlesoftware/article/details/6525628
Oracle 跟踪事件 set event
http://blog.csdn.net/tianlesoftware/article/details/4977827
Oracle 10053 事件
http://blog.csdn.net/tianlesoftware/article/details/5859027
Event 10053 执行计划绑定变量 Bind peeking
http://blog.csdn.net/tianlesoftware/article/details/5544307
Oracle SQL Trace 和 10046 事件
http://blog.csdn.net/tianlesoftware/article/details/5857023
使用 Tkprof 分析 ORACLE 跟踪文件
http://blog.csdn.net/tianlesoftware/article/details/5632003
2.5 统计信息
优化器收集的统计信息包括如下内容:
1)Table statistics
Number of rows
Number of blocks
Average row length
2)Column statistics
Number of distinctvalues (NDV) in column
Number of nulls incolumn
Data distribution(histogram)
3)Index statistics
Number of leaf blocks
Levels
Clustering factor
4)System statistics
I/O performance and utilization
CPU performance andutilization
统计信息收集如下数据:
(1)表自身的分析: 包括表中的行数,数据块数,行长等信息。
(2)列的分析:包括列值的重复数,列上的空值,数据在列上的分布情况。
(3)索引的分析: 包括索引叶块的数量,索引的深度,索引的聚合因子等。
这些统计信息存放在数据字典里,如:
(1). DBA_TABLES
(2). DBA_OBJECT_TABLES
(3). DBA_TAB_STATISTICS
(4). DBA_TAB_COL_STATISTICS
(5). DBA_TAB_HISTOGRAMS
(6). DBA_INDEXES
(7). DBA_IND_STATISTICS
(8). DBA_CLUSTERS
(9). DBA_TAB_PARTITIONS
(10).DBA_TAB_SUBPARTITIONS
(11).DBA_IND_PARTITIONS
(12).DBA_IND_SUBPARTITIONS
(13).DBA_PART_COL_STATISTICS
(14).DBA_PART_HISTOGRAMS
(15).DBA_SUBPART_COL_STATISTICS
(16).DBA_SUBPART_HISTOGRAMS
统计信息的准确程度,直接决定SQL的效率。 所以需要定期的收集相关对象的统计信息。Oracle 的Statistic 信息的收集分两种:自动收集和手工收集。
Oracle 的Automatic StatisticsGathering 是通过Scheduler 来实现收集和维护的。 Job 名称是GATHER_STATS_JOB, 该Job收集数据库所有对象的2种统计信息:
(1)Missing statistics(统计信息缺失)
(2)Stale statistics(统计信息陈旧)
该Job 是在数据库创建的时候自动创建,并由Scheduler来管理。Scheduler 在maintenance windows open时运行gather job。 默认情况下,job 会在每天晚上10到早上6点和周末全天开启。该过程首先检测统计信息缺失和陈旧的对象。然后确定优先级,再开始进行统计信息。
Scheduler Job的 stop_on_window_close 属性控制GATHER_STATS_JOB 是否继续。该属性默认值为True. 如果该值设置为False,那么GATHER_STATS_JOB 会中断,而没有收集完的对象将在下次启动时继续收集。
Gather_stats_job 调用dbms_stats.gather_database_stats_job_proc过程来收集statistics 的信息。 该过程收集对象statistics的条件如下:
(1)对象的统计信息之前没有收集过。
(2)当对象有超过10%的rows 被修改,此时对象的统计信息也称为stale statistics。
Oracle Statistic 统计信息 小结
http://blog.csdn.net/tianlesoftware/article/details/4668723
Oracle 判断 并 手动收集 统计信息 脚本
http://blog.csdn.net/tianlesoftware/article/details/6445868
三.索引
3.1 索引分类
索引对DB的性能中起着重要的作用。 Oracle 有如下类型的索引:
B树索引(默认类型)
位图索引
HASH索引
索引组织表索引
反转键(reverse key)索引
基于函数的索引
分区索引(本地和全局索引)
位图连接索引
3.2 索引限制
这部分内容应该放到SQL 编写部分,不过为了强调,还是放到这块。
即使相关字段上有索引,在如下4种情况,也不会走作引:
(1) 使用不等于操作符(<>、!=)
(2) 使用IS NULL 或IS NOT NULL
(3) 使用函数
(4) 比较不匹配的数据类型
所以在SQL 编写过程中,尽量避免以上4种情况。
具体参考:
Oracle 索引详解
http://blog.csdn.net/tianlesoftware/article/details/5347098
3.3 索引维护
这部分内容包括:
(1) 索引的选择性: distinct/rows, 接近与1,选择性越高,直方图--》数据倾斜。
(2) 索引的扩展:index segment 是由extents组成,如果extents大于10,可以考虑重建索引。
(3) 索引碎片:查询index_stats表以确定索引中删除的、未填满的叶子(Leaf)行的百分比 和 height 字段。 如果索引的叶子行的碎片超过10%,或者 index_stats中height > =4, 可以考虑对索引进行重建。
select name,height, del_lf_rows, lf_rows,round((del_lf_rows/(lf_rows+0.0000000001))*100) "Frag Percent" from index_stats
具体参考:
索引维护:
http://blog.csdn.net/tianlesoftware/article/details/5680706
3.4 索引的 Clustering Factor 参数
这个参数是个神奇的参数,先看一种情况,有的人应该遇到过,就是表的字段上有索引,但根据这个字段做查询时,却发现Oracle并没有使用索引? 并且查询条件没有限制索引。那么Oracle 为什么不走索引? 很可能就是和这个参数值有关。
可以从dba_indexes 表里查看到每个具体对象的Clustering Factor值:
select owner,index_name, clustering_factor, num_rows from dba_indexes whereowner='SYS' and index_name='IDX_T_ID';
该参数反应的是数据在物理block的上的连续性,如果该值接近于对象的block数,那么数据在block上的存储就是有序的,如果接近与表的行数,可以反应出数据的存储无序。
当数据有序时,我们查询一个数据时,可以从一个block里一次性读出,如果无序,那么我们可能就需要读取多个block,这样I/O次数增加,CBO 就会认为这种代价更大,从而选择全表扫描来代替索引。从而导致即使有索引,也不会走。
但是随着系统使用时间的越长,Clustering Factor值是会越来越大的。解决这个问题的唯一方法就是对表进行move。
具体参考:
Oracle Index Clustering Factor 说明
http://blog.csdn.net/tianlesoftware/article/details/6585453
3.5 索引扫描5种类型:
(1)index unique scan: 查询结果返回一行记录
(2)index range scan: 查询结果返回多行记录。
(3)index full scan:可能进行全Oracle索引扫描而不是范围扫描,需要注意的是全Oracle索引扫描只在CBO模式下才有效。 CBO根据统计数值得知进行全Oracle索引扫描比进行全表扫描更有效时,才进行全Oracle索引扫描,而且此时查询出的数据都必须从索引中可以直接得到。
(4)index fast full scan: 与 index full scan很类似,但是一个显著的区别就是它不对查询出的数据进行排序,即数据不是以排序顺序被返回。在这种存取方法中,可以使用多块读功能,也可以使用并行读入,以便获得最大吞吐量与缩短执行时间。
(5)index skip scan: INDEX SKIP SCAN,发生在多个列建立的复合索引上,如果SQL中谓词条件只包含索引中的部分列,并且这些列不是建立索引时的第一列时,就可能发生INDEX SKIP SCAN。这里SKIP的意思是因为查询条件没有第一列或前面几列,被忽略了。
具体参考:
Oracle 索引扫描的五种类型
http://blog.csdn.net/tianlesoftware/article/details/5852106
四.绑定变量
这个也是SQL 编写的基本功. 简单的说,使用绑定变量可以避免进行硬解析,减少对资源的消耗。
Oracle里的所有SQL 语句都是implicitly sharable的。 SQL 在执行之前,要通过一个hash 运算,生成相关的cursor。 如果通过hash 运算之后,发现已经了有对应的cursor,那就可以直接使用之前的cursor 和plan。如果不存在,就需要进行硬解析,而硬解析是一个非常耗资源的操作。需要尽量减少硬解析。
如何保证每次HASH 运算之后的hash 值都一样,那么这就需要通过绑定变来来实现。
在第一次执行执行SQL 之后,如果使用了绑定变量,那么Oracle 在硬解析的时候,会进行一个叫Peek的操作。 也可以称为偷窥。就是把实际值带进去,帮助产生更加准确的执行计划。比如对应的Peek列上有严重的数据倾斜,假设我们已经对表进行了统计信息收集,oracle 会产生该列的直方图(histogram),在peek的时候,就会根据直方图来决定,是走索引还是走全表扫描更划算。
因此第一执行产生的执行计划肯定是最优的。现在假设数据倾斜有2个值,一个占90%,一个占10%。 我们第一使用10%的值,所以第一次走索引。 那么如果我们以后在绑定时,使用了90%的值,那么这时候,Oracle 还是会使用之前的cursor,继续走索引,此时走索引就不是最优的了。
这个就是Oracle 10g里绑定变量的一个问题。 在第一次硬解析之后,以后所有的操作都会使用之前产生的cursor 和plan。所以在10g里,对于列上有严重数据倾斜的,最好是不采用绑定变量。
在Oracle 11g里,对这个问题,进行了优化,使用了Adaptive Cursor Sharing,它可以产生多个共享cursor。如果是90%的值,就使用cursor 1,如果是10%的cursor,就使用corsor 2. 在这个转换的过程中还是有可能再次产生硬解析。
Oracle 11g的绑定变量处理过程如下:
当我们第一去执行一个带有绑定变量的SQL时,Oracle 会进行硬解析,但是硬解析不能确定最优的执行计划,所以这时候有了Peek。 也可以说是偷窥,即把实际值带入,来生成一个selectivity estimate。 然后来选择最优的一个执行计划来执行。
这是第一次执行SQL语句。以后执行时就会使用已经存在的plan和cursor。 Oracle 通过Adaptive Cursor Sharing特性允许同一个SQL 可以使用多个执行计划。
在每次执行时,Oracle会根据Peek 的selectivity estimate 值和直方图(如果存在)来判断已经存在的cursor 是否是最优的,如果不是,就重新创建一个child cursor,并讲Bind-Sensitive 标记为Y。
而且Oracle在SQL 每次执行时,都会收集相关的统计信息,然后根据统计信息进行判断,如果比上次的更好,就在创建一个child cursor,并将Bind-Aware 标记为Y。
当标记为bind-aware cursor 的cursor在下次执行时,Oracle根据新的bind value 来生成新的plan和cursor,并将原来的cursor标记为非共享,即V$SQL.IS_SHAREABLE 设置为 N,当这种cursor 长期不被使用时, 就会被移出shared SQL area.
在bind-aware cursor创建新的cursor 之后,如果这个cursor 和之前某个存在的cursor一样,那么Oracle 会对他们进行合并。
如果在cache里不能找到bind-aware对应的plan,那么就会重新进行一次硬解析,来生成plan 和cursor,如果这个plan 以后被新的cursor 使用,那么Oracle 会将这2个cursor 进行合并。
Oracle 绑定变量 详解
http://blog.csdn.net/tianlesoftware/article/details/5856430
Oracle 绑定变量 示例
http://blog.csdn.net/tianlesoftware/article/details/6324243
Oracle 10g 与 11g 绑定变量(Bind Variable) 区别 说明
http://blog.csdn.net/tianlesoftware/article/details/6591222
对于绑定变量的cursor 能否重用,与Cursor_sharing 参数有很大关系。具体参考:
Oracle cursor_sharing 参数 详解
http://blog.csdn.net/tianlesoftware/article/details/6551723
Oracle Library cache 内部机制 说明
http://blog.csdn.net/tianlesoftware/article/details/6629869
五.其他与SQL 性能相关的链接
Oracle Sequence Cache 参数说明
http://blog.csdn.net/tianlesoftware/article/details/5995051
Oracle bulk 示例
http://blog.csdn.net/tianlesoftware/article/details/6599003
Oracle Bulk 与 性能优化 说明
http://blog.csdn.net/tianlesoftware/article/details/6578351
Oracle Pipelined TableFunctions 与 性能优化 说明
http://blog.csdn.net/tianlesoftware/article/details/6601540
Oracle arraysize 和 fetchsize 参数 与 性能优化 说明
http://blog.csdn.net/tianlesoftware/article/details/6579913
Oracle 利用 rowid 提升 update 性能
http://blog.csdn.net/tianlesoftware/article/details/6576156
Oracle Parallel Execution(并行执行)
http://blog.csdn.net/tianlesoftware/article/details/5854583
相关推荐
总结来说,Oracle SQL优化是一个综合性的任务,需要考虑索引、连接方式、查询结构等多个方面。理解并应用上述知识点,能够帮助你更好地管理和优化你的Oracle数据库,实现更高效的SQL执行。通过持续学习和实践,你...
简单的整理了一些Oracle性能优化方面的知识。 供大家参考学习。
Oracle数据库SQL优化是一个关键的技能,对于提升数据库性能和应用响应速度至关重要。以下是一些针对非DBA的Oracle SQL优化技巧: 1. **选择最有效的表名顺序**:在FROM子句中,应将记录最少的表放在最前面,基础表...
### Oracle SQL性能优化技巧总结 #### 一、选择最有效率的表名顺序 在Oracle数据库中,SQL语句的执行顺序对查询性能有着显著的影响。对于基于规则的优化器而言,FROM子句中表的顺序至关重要。Oracle的解析器会按照...
ORACLE SQL 优化存储过程 PROCEDURE ORACLE SQL 优化存储过程 PROCEDURE 是一篇结合实际开发经验和理论知识的文章,旨在帮助开发者提高 SQL 开发效率和优化存储过程。文章涵盖了广泛的知识点,从基本的 SQL 语句到...
### Oracle 性能优化之 SQL优化 #### 一、引言 在数据库应用中,SQL查询性能直接影响到系统的响应时间和整体性能。对于大型企业级应用而言,优化SQL语句不仅能够提升用户体验,还能显著降低服务器负载,从而节省...
### Oracle SQL性能优化技巧大总结 #### 一、选择最有效率的表名顺序 **背景**:在基于规则的优化器(RBO)中,Oracle解析器处理FROM子句中的表名是从右向左的。为了提高查询效率,需要合理安排表的顺序。 **技巧...
总结,Oracle SQL优化是一个综合性的过程,涉及到SQL语句的编写、数据库结构的设计、索引的管理和优化器的配置等多个方面。通过对上述策略的理解和应用,可以显著提高Oracle数据库的性能和响应速度,为用户提供更好...
Oracle SQL性能优化是数据库管理员和开发人员的关键技能,它直接影响到应用程序的响应时间和资源消耗。以下是对标题和描述中提到的一些关键知识点的详细解释: 1. **选择最有效率的表名顺序**:在基于规则的优化器...
【超易懂实用,初学者必看】oracleSQL优化培训,由企业dba切身实际经验总结,超简单易懂超实用,初入门者不看必后悔!!
总结来说,ORACLE数据库中SQL优化是一个复杂的课题,它需要了解SQL语句的执行过程,掌握优化器的工作原理,能够合理设置和调整优化器参数,并且熟练运用索引优化等技术手段。通过对这些关键知识点的理解和应用,可以...
### ORACLE中SQL查询优化技术 #### 一、引言 在现代企业级数据库应用中,Oracle数据库因其高性能、高可靠性和丰富的功能被广泛采用。然而,在实际的应用场景下,即使是设计良好的数据库系统也可能因为查询效率低下...
Oracle数据库SQL优化是一个复杂而重要的主题,涉及到许多技术细节和策略。以下是对标题和描述中提到的优化点的详细说明: 1. **使用`WHERE`少使用`HAVING`**: - `WHERE`子句在SQL查询中用于在数据筛选阶段过滤行...
本文将围绕Oracle SQL优化展开,深入探讨如何通过各种技术手段来提升查询性能。 首先,理解SQL执行过程是优化的基础。在Oracle数据库中,SQL语句的执行涉及到解析、优化和执行三个主要阶段。解析阶段确定语句的语法...
总结来说,Oracle的数据库和SQL优化是一个涉及多个层面的综合过程,需要考虑数据库架构、数据存储方式、查询效率以及优化器的合理使用等多个方面的因素。通过对这些方面的综合考虑,可以显著提升Oracle数据库的性能...
以下是对SQL优化的总结,主要聚焦于Oracle数据库的SQL语句调优。 1. **理解执行计划**:优化SQL的第一步是理解查询的执行计划。Oracle的`EXPLAIN PLAN`可以展示SQL执行的步骤,包括表扫描方式、连接顺序、索引使用...
因此,对Oracle SQL的性能优化是数据库管理员和开发人员必须掌握的重要技能。本文档将介绍一些针对Oracle SQL的性能优化的方法和技巧,并在实际操作中如何根据服务器的实际情况做出调整。 一、Oracle优化器的选取 ...
SQL性能优化是数据库...总结来说,Oracle数据库的SQL性能优化是一个综合性的过程,涉及需求分析、规范化设计、查询优化技术和持续的数据库维护。通过全面考虑这些因素,可以构建出高效、稳定且易于管理的数据库系统。
【ORACLE SQL语句优化总结】 在Oracle数据库中,SQL语句的优化是提升系统性能的关键环节。以下是一些常见的优化策略: 1)选择最有效的表名顺序:Oracle的解析器按照FROM子句中表的右到左顺序处理,基础表...