??xml version="1.0" encoding="utf-8" standalone="yes"?>波多野结衣在线,999精品视频,精品欧美不卡一区二区在线观看http://www.aygfsteel.com/codechris/category/44756.htmli can do thiszh-cnSat, 13 Apr 2013 23:07:14 GMTSat, 13 Apr 2013 23:07:14 GMT60OracleSQL 优化http://www.aygfsteel.com/codechris/archive/2013/04/09/397579.htmlcodechriscodechrisTue, 09 Apr 2013 05:35:00 GMThttp://www.aygfsteel.com/codechris/archive/2013/04/09/397579.htmlhttp://www.aygfsteel.com/codechris/comments/397579.htmlhttp://www.aygfsteel.com/codechris/archive/2013/04/09/397579.html#Feedback0http://www.aygfsteel.com/codechris/comments/commentRss/397579.htmlhttp://www.aygfsteel.com/codechris/services/trackbacks/397579.html

Q?Q?nbsp;选择最有效率的表名序(只在Z规则的优化器中有?Q?br style="word-break: break-all; line-height: normal !important; " />ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名QFROM子句中写在最后的?基础?driving table)被最先处理,在FROM子句中包含多个表的情况下,你必选择记录条数最的表作为基表。如果有3个以上的表连接查? 那就需要选择交叉?intersection table)作ؓ(f)基础? 交叉表是指那个被其他表所引用的表.
Q?Q?nbsp;WHERE子句中的q接序Q:(x)
ORACLE采用自下而上的顺序解析WHERE子句,Ҏ(gu)q个原理,表之间的q接必须写在其他WHERE条g之前, 那些可以qo(h)掉最大数量记录的条g必须写在WHERE子句的末?
Q?Q?nbsp;SELECT子句中避免?‘ * ‘Q?br style="word-break: break-all; line-height: normal !important; " />ORACLE在解析的q程? ?x)?*' 依次转换成所有的列名, q个工作是通过查询数据字典完成? q意味着耗费更多的时?br style="word-break: break-all; line-height: normal !important; " />Q?Q?nbsp;减少讉K数据库的ơ数Q?br style="word-break: break-all; line-height: normal !important; " />ORACLE在内部执行了(jin)许多工作: 解析SQL语句, 估算索引的利用率, l定变量 , L据块{;
Q?Q?nbsp;在SQL*Plus , SQL*Forms和Pro*C中重新设|ARRAYSIZE参数, 可以增加每次数据库访问的(g)索数据量 ,gؓ(f)200
Q?Q?nbsp;使用DECODE函数来减处理时_(d)(x)
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的?
Q?Q?nbsp;整合?无关联的数据库访问:(x)
如果你有几个单的数据库查询语?你可以把它们整合C个查询中(即它们之间没有关系)
Q?Q?nbsp;删除重复记录Q?br style="word-break: break-all; line-height: normal !important; " />最高效的删除重复记录方?( 因ؓ(f)使用?jin)ROWID)例子Q?br style="word-break: break-all; line-height: normal !important; " />DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) 
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
Q?Q?nbsp;用TRUNCATE替代DELETEQ?br style="word-break: break-all; line-height: normal !important; " />当删除表中的记录?在通常情况? 回滚D?rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE?x)将数据恢复到删除之前的状?准确地说是恢复到执行删除命o(h)之前的状? 而当q用TRUNCATE? 回滚D不再存放Q何可被恢复的信息.当命令运行后,数据不能被恢?因此很少的资源被调用,执行旉也会(x)很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
Q?0Q?nbsp;量多用COMMITQ?br style="word-break: break-all; line-height: normal !important; " />只要有可?在程序中量多用COMMIT, q样E序的性能得到提高,需求也?x)因为COMMIT所释放的资源而减? 
COMMIT所释放的资? 
a. 回滚D上用于恢复数据的信? 
b. 被程序语句获得的?nbsp;
c. redo log buffer 中的I间 
d. ORACLE为管理上q?U资源中的内部花?br style="word-break: break-all; line-height: normal !important; " />Q?1Q?nbsp;用Where子句替换HAVING子句Q?br style="word-break: break-all; line-height: normal !important; " />避免使用HAVING子句, HAVING 只会(x)在检索出所有记录之后才对结果集q行qo(h). q个处理需要排?总计{操? 如果能通过WHERE子句限制记录的数?那就能减这斚w的开销. (非oracle?on、where、havingq三个都可以加条件的子句中,on是最先执行,whereơ之Qhaving最后,因ؓ(f)on是先把不W合条g的记录过滤后才进行统计,它就可以减少中间q算要处理的数据Q按理说应该速度是最快的Qwhere也应该比having快点的,因ؓ(f)它过滤数据后才进行sumQ在两个表联接时才用on的,所以在一个表的时候,剩下where跟having比较?jin)。在q单表查询统计的情况下,如果要过滤的条g没有涉及(qing)到要计算字段Q那它们的结果是一L(fng)Q只是where可以使用rushmore技术,而having׃能,在速度上后者要慢如果要涉及(qing)到计的字段Q就表示在没计算之前Q这个字D늚值是不确定的Q根据上写的工作流E,where的作用时间是在计之前就完成的,而having是在计后才v作用的,所以在q种情况下,两者的l果?x)不同。在多表联接查询Ӟon比where更早起作用。系l首先根据各个表之间的联接条Ӟ把多个表合成一个(f)时表后,再由whereq行qo(h)Q然后再计算Q计完后再由havingq行qo(h)。由此可见,要想qo(h)条g起到正确的作用,首先要明白这个条件应该在什么时候v作用Q然后再军_攑֜那里
Q?2Q?nbsp;减少对表的查询:(x)
在含有子查询的SQL语句?要特别注意减对表的查询.例子Q?br style="word-break: break-all; line-height: normal !important; " />SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
Q?3Q?nbsp;通过内部函数提高SQL效率.Q?br style="word-break: break-all; line-height: normal !important; " />复杂的SQL往往牺牲?jin)执行效? 能够掌握上面的运用函数解决问题的Ҏ(gu)在实际工作中是非常有意义?br style="word-break: break-all; line-height: normal !important; " />Q?4Q?nbsp;使用表的别名(Alias)Q?br style="word-break: break-all; line-height: normal !important; " />当在SQL语句中连接多个表? 请用表的别名ƈ把别名前~于每个Column?q样一?可以减解析的旉q减那些由Column歧义引v的语法错?
Q?5Q?nbsp;用EXISTS替代IN、用NOT EXISTS替代NOT INQ?br style="word-break: break-all; line-height: normal !important; " />在许多基于基表的查询?Z(jin)满一个条?往往需要对另一个表q行联接.在这U情况下, 使用EXISTS(或NOT EXISTS)通常提高查询的效率. 在子查询?NOT IN子句执行一个内部的排序和合q? 无论在哪U情况下,NOT IN都是最低效?(因ؓ(f)它对子查询中的表执行?jin)一个全表遍?. Z(jin)避免使用NOT IN ,我们可以把它改写成外q接(Outer Joins)或NOT EXISTS.
例子Q?br style="word-break: break-all; line-height: normal !important; " />Q高效)(j)SELECT * FROM EMP (基础? WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB')
(低效)SELECT * FROM EMP (基础? WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB')
Q?6Q?nbsp;识别'低效执行'的SQL语句Q?/strong>
虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始l是一个最好的Ҏ(gu)Q?br style="word-break: break-all; line-height: normal !important; " />SELECT EXECUTIONS , DISK_READS, BUFFER_GETS, 
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio, 
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run, 
SQL_TEXT 
FROM V$SQLAREA 
WHERE EXECUTIONS>0 
AND BUFFER_GETS > 0 
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 
ORDER BY 4 DESC;

Q?7Q?nbsp;用烦(ch)引提高效率:(x)
索引是表的一个概念部?用来提高?gu)(g)索数据的效率QORACLE使用?jin)一个复杂的自^衡B-treel构. 通常,通过索引查询数据比全表扫描要? 当ORACLE扑և执行查询和Update语句的最佌\径时, ORACLE优化器将使用索引. 同样在联l多个表时用烦(ch)引也可以提高效率. 另一个用烦(ch)引的好处?它提供了(jin)主键(primary key)的唯一性验?。那些LONG或LONG RAW数据cd, 你可以烦(ch)引几乎所有的? 通常, 在大型表中用烦(ch)引特别有? 当然,你也?x)发? 在扫描小表时,使用索引同样能提高效? 虽然使用索引能得到查询效率的提高,但是我们也必L意到它的代h(hun). 索引需要空间来存储,也需要定期维? 每当有记录在表中增减或烦(ch)引列被修Ҏ(gu), 索引本n也会(x)被修? q意味着每条记录的INSERT , DELETE , UPDATEؓ(f)此多付出4 , 5 ơ的盘I(y)/O . 因ؓ(f)索引需要额外的存储I间和处?那些不必要的索引反而会(x)使查询反应时间变?。定期的重构索引是有必要?Q?br style="word-break: break-all; line-height: normal !important; " />ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
Q?8Q?nbsp;用EXISTS替换DISTINCTQ?br style="word-break: break-all; line-height: normal !important; " />当提交一个包含一对多表信?比如部门表和雇员?的查询时,避免在SELECT子句中用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更?因ؓ(f)RDBMS核心(j)模块在子查询的条g一旦满_,立刻q回l果. 例子Q?br style="word-break: break-all; line-height: normal !important; " />(低效): 
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E 
WHERE D.DEPT_NO = E.DEPT_NO 
(高效): 
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' 
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
Q?9Q?nbsp;sql语句用大写的Q因为oracleL先解析sql语句Q把写的字母{换成大写的再执行
Q?0Q?nbsp;在java代码中尽量少用连接符“Q?#8221;q接字符Ԍ
Q?1Q?nbsp;避免在烦(ch)引列上用NOT 通常Q 
我们要避免在索引列上使用NOT, NOT?x)生在和在索引列上使用函数相同的?jing)? 当ORACLE”遇到”NOT,他就?x)停止用?ch)引{而执行全表扫?
Q?2Q?nbsp;避免在烦(ch)引列上用计.
WHERE子句中,如果索引列是函数的一部分Q优化器不使用索引而用全表扫描. 
举例: 
低效Q?nbsp;
SELECT … FROM DEPT WHERE SAL * 12 > 25000; 
高效: 
SELECT … FROM DEPT WHERE SAL > 25000/12;
Q?3Q?nbsp;?gt;=替代>
高效: 
SELECT * FROM EMP WHERE DEPTNO >=4 
低效: 
SELECT * FROM EMP WHERE DEPTNO >3 
两者的区别在于, 前者DBMS直接蟩到第一个DEPT{于4的记录而后者将首先定位到DEPTNO=3的记录ƈ且向前扫描到W一个DEPT大于3的记?
Q?4Q?nbsp;用UNION替换OR (适用于烦(ch)引列)
通常情况? 用UNION替换WHERE子句中的OR会(x)起到较好的效? 对烦(ch)引列使用OR造成全表扫描. 注意, 以上规则只针对多个烦(ch)引列有效. 如果有column没有被烦(ch)? 查询效率可能?x)因Z没有选择OR而降? 在下面的例子? LOC_ID 和REGION上都建有索引. 
高效: 
SELECT LOC_ID , LOC_DESC , REGION 
FROM LOCATION 
WHERE LOC_ID = 10 
UNION 
SELECT LOC_ID , LOC_DESC , REGION 
FROM LOCATION 
WHERE REGION = “MELBOURNE” 
低效: 
SELECT LOC_ID , LOC_DESC , REGION 
FROM LOCATION 
WHERE LOC_ID = 10 OR REGION = “MELBOURNE” 
如果你坚持要用OR, 那就需要返回记录最的索引列写在最前面.
Q?5Q?nbsp;用IN来替换OR 
q是一条简单易记的规则Q但是实际的执行效果q须(g)验,在ORACLE8i下,两者的执行路径g是相同的Q 
低效: 
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30 
高效 
SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);
Q?6Q?nbsp;避免在烦(ch)引列上用IS NULL和IS NOT NULL
避免在烦(ch)引中使用M可以为空的列QORACLE无法用该索引Q对于单列烦(ch)引,如果列包含空|索引中将不存在此记录. 对于复合索引Q如果每个列都ؓ(f)I,索引中同样不存在此记? 如果臛_有一个列不ؓ(f)I,则记录存在于索引中.举例: 如果唯一性烦(ch)引徏立在表的A列和B列上, q且表中存在一条记录的A,Bgؓ(f)(123,null) , ORACLE不接受下一条具有相同A,B|123,nullQ的记录(插入). 然而如果所有的索引列都为空QORACLE认为整个键gؓ(f)I空不等于空. 因此你可以插?000 条具有相同键值的记录,当然它们都是I? 因ؓ(f)Ig存在于烦(ch)引列?所以WHERE子句中对索引列进行空值比较将使ORACLE停用该烦(ch)?
低效: (索引失效) 
SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL; 
高效: (索引有效) 
SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;
Q?7Q?nbsp;L使用索引的第一个列Q?/strong>
如果索引是徏立在多个列上, 只有在它的第一个列(leading column)被where子句引用?优化器才?x)选择使用该烦(ch)? q也是一条简单而重要的规则Q当仅引用烦(ch)引的W二个列?优化器用了(jin)全表扫描而忽略了(jin)索引
Q?8Q?nbsp;用UNION-ALL 替换UNION ( 如果有可能的?Q?/strong>
当SQL语句需要UNION两个查询l果集合?q两个结果集合会(x)以UNION-ALL的方式被合ƈ, 然后在输出最l结果前q行排序. 如果用UNION ALL替代UNION, q样排序׃是必要了(jin). 效率׃(x)因此得到提高. 需要注意的是,UNION ALL 重复输Z个结果集合中相同记录. 因此各位q是要从业务需求分析用UNION ALL的可行? UNION 对l果集合排序,q个操作?x)用到SORT_AREA_SIZEq块内存. 对于q块内存的优化也是相当重要的. 下面的SQL可以用来查询排序的消耗量
低效Q?nbsp;
SELECT ACCT_NUM, BALANCE_AMT 
FROM DEBIT_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95' 
UNION 
SELECT ACCT_NUM, BALANCE_AMT 
FROM DEBIT_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95' 
高效: 
SELECT ACCT_NUM, BALANCE_AMT 
FROM DEBIT_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95' 
UNION ALL 
SELECT ACCT_NUM, BALANCE_AMT 
FROM DEBIT_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95'
Q?9Q?nbsp;用WHERE替代ORDER BYQ?/strong>
ORDER BY 子句只在两种严格的条件下使用索引. 
ORDER BY中所有的列必d含在相同的烦(ch)引中q保持在索引中的排列序. 
ORDER BY中所有的列必d义ؓ(f)非空. 
WHERE子句使用的烦(ch)引和ORDER BY子句中所使用的烦(ch)引不能ƈ?
例如: 
表DEPT包含以下? 
DEPT_CODE PK NOT NULL 
DEPT_DESC NOT NULL 
DEPT_TYPE NULL
低效: (索引不被使用) 
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE 
高效: (使用索引) 
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0
Q?0Q?nbsp;避免改变索引列的cd.:
当比较不同数据类型的数据? ORACLE自动对列q行单的cd转换. 
假设 EMPNO是一个数值类型的索引? 
SELECT … FROM EMP WHERE EMPNO = ‘123' 
实际?l过ORACLEcd转换, 语句转化? 
SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(‘123') 
q运的是,cd转换没有发生在烦(ch)引列?索引的用途没有被改变. 
现在,假设EMP_TYPE是一个字W类型的索引? 
SELECT … FROM EMP WHERE EMP_TYPE = 123 
q个语句被ORACLE转换? 
SELECT … FROM EMP WHERETO_NUMBER(EMP_TYPE)=123 
因ؓ(f)内部发生的类型{? q个索引不?x)被用? Z(jin)避免ORACLE对你的SQLq行隐式的类型{? 最好把cd转换用显式表现出? 注意当字W和数值比较时, ORACLE?x)优先{换数值类型到字符cd
Q?1Q?nbsp;需要当?j)的WHERE子句:
某些SELECT 语句中的WHERE子句不用烦(ch)? q里有一些例? 
在下面的例子? (1)‘!=' 不使用索引. C, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表? (2) ‘||'是字W连接函? p其他函数那样, 停用?jin)?ch)? (3) ‘+'是数学函? p其他数学函数那样, 停用?jin)?ch)? (4)相同的烦(ch)引列不能互相比较,q将?x)启用全表扫?
Q?2Q?nbsp;a. 如果(g)索数据量过30%的表中记录数.使用索引没有显著的效率提高. 
b. 在特定情况下, 使用索引也许?x)比全表扫描? 但这是同一个数量上的区别. 而通常情况?使用索引比全表扫描要块几倍乃臛_千?
Q?3Q?nbsp;避免使用耗费资源的操?
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句?x)启动SQL引擎 
执行耗费资源的排?SORT)功能. DISTINCT需要一ơ排序操? 而其他的臛_需要执行两ơ排? 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑? 毕竟它们的可L很?br style="word-break: break-all; line-height: normal !important; " />Q?4Q?nbsp;优化GROUP BY:
提高GROUP BY 语句的效? 可以通过不需要的记录在GROUP BY 之前qo(h)?下面两个查询q回相同l果但第二个明显快?jin)许?
低效: 
SELECT JOB , AVG(SAL) 
FROM EMP 
GROUP JOB 
HAVING JOB = ‘PRESIDENT' 
OR JOB = ‘MANAGER' 
高效: 
SELECT JOB , AVG(SAL) 
FROM EMP 
WHERE JOB = ‘PRESIDENT' 
OR JOB = ‘MANAGER' 
GROUP JOB



codechris 2013-04-09 13:35 发表评论
]]>
վ֩ģ壺 Ϫ| û| ɽ| Ͽ| ϳ| ̨| | | ݰ| | ɽ| ˶| ˷| | | | | Ѿ| ͨ| | | | | | | | ȫ| ͨɽ| ̰| ӳ| | | | | ɽ| | Զ| ;| | | Դ|