??xml version="1.0" encoding="utf-8" standalone="yes"?>日韩免费特黄一二三区,国产一区二区三区四区三区四 ,亚洲一区二区在线免费观看http://www.aygfsteel.com/harrygoo/category/49691.htmlzh-cnWed, 28 Sep 2011 01:08:42 GMTWed, 28 Sep 2011 01:08:42 GMT60SQL优化34? http://www.aygfsteel.com/harrygoo/articles/359396.htmlharrygooharrygooSat, 24 Sep 2011 00:41:00 GMThttp://www.aygfsteel.com/harrygoo/articles/359396.html
我们要做C但会(x)写SQL,q要做到写出性能优良的SQL,以下为笔者学?fn)、摘录、ƈ汇总部分资料与大家分nQ?br />Q?Q?选择最有效率的表名序(只在Z规则的优化器中有?Q?br />ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名QFROM子句中写在最后的?基础?driving table)被最先处理,在FROM子句中包含多个表的情况下,你必选择记录条数最的表作为基表。如果有3个以上的表连接查? 那就需要选择交叉?intersection table)作ؓ(f)基础? 交叉表是指那个被其他表所引用的表.
Q?Q?WHERE子句中的q接序Q:(x)
ORACLE采用自下而上的顺序解析WHERE子句,Ҏ(gu)q个原理,表之间的q接必须写在其他WHERE条g之前, 那些可以qo(h)掉最大数量记录的条g必须写在WHERE子句的末?
Q?Q?SELECT子句中避免?‘ * ‘Q?br />ORACLE在解析的q程? ?x)?*' 依次转换成所有的列名, q个工作是通过查询数据字典完成? q意味着耗费更多的时?br />Q?Q?减少讉K数据库的ơ数Q?br />ORACLE在内部执行了(jin)许多工作: 解析SQL语句, 估算索引的利用率, l定变量 , L据块{;
Q?Q?在SQL*Plus , SQL*Forms和Pro*C中重新设|ARRAYSIZE参数, 可以增加每次数据库访问的(g)索数据量 ,gؓ(f)200
Q?Q?使用DECODE函数来减处理时_(d)(x)
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的?
Q?Q?整合?无关联的数据库访问:(x)
如果你有几个单的数据库查询语?你可以把它们整合C个查询中(即它们之间没有关系)
Q?Q?删除重复记录Q?br />最高效的删除重复记录方?( 因ؓ(f)使用?jin)ROWID)例子Q?br />DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)  
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
Q?Q?用TRUNCATE替代DELETEQ?br />?删除表中的记录时,在通常情况? 回滚D?rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE?x)将数据恢复到删除之前的状?准确地说是恢复到执行删除命o(h)之前的状? 而当q用TRUNCATE? 回滚D不再存放Q何可被恢复的信息.当命令运行后,数据不能被恢?因此很少的资源被调用,执行旉也会(x)很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
Q?0Q?量多用COMMITQ?br />只要有可?在程序中量多用COMMIT, q样E序的性能得到提高,需求也?x)因为COMMIT所释放的资源而减?  
COMMIT所释放的资?  
a. 回滚D上用于恢复数据的信?  
b. 被程序语句获得的?nbsp; 
c. redo log buffer 中的I间  
d. ORACLE为管理上q?U资源中的内部花?br />Q?1Q?用Where子句替换HAVING子句Q?br />?免用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)到计的?D,pC在没计之前,q个字段的值是不确定的Q根据上写的工作流E,where的作用时间是在计之前就完成的,而having是在计后才v?用的Q所以在q种情况下,两者的l果?x)不同。在多表联接查询Ӟon比where更早起作用。系l首先根据各个表之间的联接条Ӟ把多个表合成一个(f)时表 后,再由whereq行qo(h)Q然后再计算Q计完后再由havingq行qo(h)。由此可见,要想qo(h)条g起到正确的作用,首先要明白这个条件应该在什么时?起作用,然后再决定放在那?br />Q?2Q?减少对表的查询:(x)
在含有子查询的SQL语句?要特别注意减对表的查询.例子Q?br />  SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
Q?3Q?通过内部函数提高SQL效率.Q?br />复杂的SQL往往牺牲?jin)执行效? 能够掌握上面的运用函数解决问题的Ҏ(gu)在实际工作中是非常有意义?br />Q?4Q?使用表的别名(Alias)Q?br />当在SQL语句中连接多个表? 请用表的别名ƈ把别名前~于每个Column?q样一?可以减解析的旉q减那些由Column歧义引v的语法错?
Q?5Q?用EXISTS替代IN、用NOT EXISTS替代NOT INQ?br />?许多Z基础表的查询?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 />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?识别'低效执行'的SQL语句Q?br />虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始l是一个最好的Ҏ(gu)Q?br />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?用烦(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 />ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
18Q?用EXISTS替换DISTINCTQ?br />当提交一个包含一对多表信?比如部门表和雇员?的查询时,避免在SELECT子句中用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更?因ؓ(f)RDBMS核心(j)模块在子查询的条g一旦满_,立刻q回l果. 例子Q?br />  (低效):  
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?sql语句用大写的Q因为oracleL先解析sql语句Q把写的字母{换成大写的再执行
Q?0Q?在java代码中尽量少用连接符“Q?#8221;q接字符Ԍ
Q?1Q?避免在烦(ch)引列上用NOT 通常Q 
我们要避免在索引列上使用NOT, NOT?x)生在和在索引列上使用函数相同的?jing)? 当ORACLE”遇到”NOT,他就?x)停止用?ch)引{而执行全表扫?
Q?2Q?避免在烦(ch)引列上用计.
WHERE子句中,如果索引列是函数的一部分Q优化器不使用索引而用全表扫描.  
举例:  
低效Q?nbsp; 
SELECT … FROM DEPT WHERE SAL * 12 > 25000;  
高效:  
SELECT … FROM DEPT WHERE SAL > 25000/12;
Q?3Q??gt;=替代>
高效:  
SELECT * FROM EMP WHERE DEPTNO >=4  
低效:  
SELECT * FROM EMP WHERE DEPTNO >3  
两者的区别在于, 前者DBMS直接蟩到第一个DEPT{于4的记录而后者将首先定位到DEPTNO=3的记录ƈ且向前扫描到W一个DEPT大于3的记?
Q?4Q?用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?用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?避免在烦(ch)引列上用IS NULL和IS NOT NULL
?免在索引中用Q何可以ؓ(f)I的列,ORACLE无法用该索引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?L使用索引的第一个列Q?br />如果索引是徏立在多个列上, 只有在它的第一个列(leading column)被where子句引用?优化器才?x)选择使用该烦(ch)? q也是一条简单而重要的规则Q当仅引用烦(ch)引的W二个列?优化器用了(jin)全表扫描而忽略了(jin)索引
28Q?用UNION-ALL 替换UNION ( 如果有可能的?Q?br />当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?用WHERE替代ORDER BYQ?br />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?避免改变索引列的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?需要当?j)的WHERE子句:
某些SELECT 语句中的WHERE子句不用烦(ch)? q里有一些例?  
?下面的例子里, (1)‘!=' 不使用索引. C, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表? (2) ‘||'是字W连接函? p其他函数那样, 停用?jin)?ch)? (3) ‘+'是数学函? p其他数学函数那样, 停用?jin)?ch)? (4)相同的烦(ch)引列不能互相比较,q将?x)启用全表扫?
Q?2Q?a. 如果(g)索数据量过30%的表中记录数.使用索引没有显著的效率提高.  
b. 在特定情况下, 使用索引也许?x)比全表扫描? 但这是同一个数量上的区别. 而通常情况?使用索引比全表扫描要块几倍乃臛_千?
Q?3Q?避免使用耗费资源的操?
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句?x)启动SQL引擎  
?行耗费资源的排?SORT)功能. DISTINCT需要一ơ排序操? 而其他的臛_需要执行两ơ排? 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑? 毕竟它们的可L很?br />Q?4Q?优化GROUP BY:
提高GROUP BY 语句的效? 可以通过不需要的记录在GROUP BY 之前qo(h)?下面两个查询q回相同l果但第二个明显快?jin)许?
低效:  
SELECT JOB , AVG(SAL)  
FROM EMP  
GROUP by JOB  
HAVING JOB = ‘PRESIDENT'  
OR JOB = ‘MANAGER'  
高效:  
SELECT JOB , AVG(SAL)  
FROM EMP  
WHERE JOB = ‘PRESIDENT'  
OR JOB = ‘MANAGER'  
GROUP by JOB


harrygoo 2011-09-24 08:41 发表评论
]]>
oracle中的exists 和not exists 用法详解 http://www.aygfsteel.com/harrygoo/articles/359395.htmlharrygooharrygooSat, 24 Sep 2011 00:16:00 GMThttp://www.aygfsteel.com/harrygoo/articles/359395.html

有两个简单例子,以说?“exists”?#8220;in”的效率问?/p>

1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ;

    T1数据量小而T2数据量非常大ӞT1<<T2 Ӟ1) 的查询效率高?/p>

2) select * from T1 where T1.a in (select T2.a from T2) ;

     T1数据量非常大而T2数据量小ӞT1>>T2 Ӟ2) 的查询效率高?/p>

exists 用法Q?/p>

h?1Q句中的有颜色字体的部分 Q理解其含义Q?/p>

其中 “select 1 from T2 where T1.a=T2.a” 相当于一个关联表查询Q相当于

“select 1 from T1,T2     where T1.a=T2.a”

但是Q如果你当当执行 1Q?句括号里的语句,是会(x)报语法错误的Q这也是使用exists需要注意的地方?/p>

“existsQxxxQ?#8221;pC括号里的语句能不能查出记录Q它要查的记录是否存在?/p>

因此“select 1”q里?“1”其实是无关紧要的Q换?#8220;*”也没问题Q它只在乎括号里的数据能不能查找出来Q是否存在这L(fng)记录Q如果存在,q?1Q?句的where 条g成立?/p>

 

in 的用法:(x)

l箋引用上面的例?/p>

“2) select * from T1 where T1.a in (select T2.a from T2) ”

q里?#8220;in”后面括号里的语句搜烦(ch)出来的字D늚内容一定要相对应,一般来_(d)T1和T2q两个表的a字段表达的意义应该是一L(fng)Q否则这h没什么意义?/p>

打个比方QT1QT2表都有一个字D,表示工单P但是T1表示工单L(fng)字段名叫“ticketid”QT2则ؓ(f)“id”Q但是其表达的意义是一L(fng)Q而且数据格式也是一L(fng)。这Ӟ?2Q的写法可以这P(x)

“select * from T1 where T1.ticketid in (select T2.id from T2) ”

Select name from employee where name not in (select name from student);

Select name from employee where not exists (select name from student);

W一句SQL语句的执行效率不如第二句?/p>

通过使用EXISTSQOracle?x)首先检查主查询Q然后运行子查询直到它找到第一个匹?,q就节省?jin)时间。Oracle在执行IN子查询时Q首先执行子查询Qƈ获得的l果列表存放在一个加?jin)?ch)引的临时表中。在执行子查询之前,pȝ先将?查询挂vQ待子查询执行完毕,存放在(f)时表中以后再执行L询。这也就是用EXISTS比用IN通常查询速度快的原因?/p>

————————————————————————————————————————————————————————————————————————————


在Oracle SQL中取数据时有时要用到in ?exists 那么他们有什么区别呢Q?/p>

1 性能上的比较

比如Select * from T1 where x in ( select y from T2 )

执行的过E相当于:

select *

  from t1, ( select distinct y from t2 ) t2

 where t1.x = t2.y;

相对?/p>

select * from t1 where exists ( select null from t2 where y = x )

执行的过E相当于:

for x in ( select * from t1 )

   loop

      
if ( exists ( select null from t2 where y = x.x )

      
then

         OUTPUT THE RECORD

      
end if

end loop

?nbsp;T1 不可避免的要被完全扫描一?/p>

分别适用在什么情?

以子查询 ( select y from T2 )虑方向

如果子查询的l果集很大需要消耗很多时_(d)但是T1比较?yu)执? select null from t2 where y = x.x )非常快,那么exists比较适合用在q里

相对应得子查询的l果集比较小的时候就应该使用in.


 



harrygoo 2011-09-24 08:16 发表评论
]]>
索引与约? http://www.aygfsteel.com/harrygoo/articles/359394.htmlharrygooharrygooFri, 23 Sep 2011 23:47:00 GMThttp://www.aygfsteel.com/harrygoo/articles/359394.html阅读全文

harrygoo 2011-09-24 07:47 发表评论
]]>
վ֩ģ壺 Ǩ| | | Ӧ| | | | | °| ʯ| | Ԫ| | | ɽ| ̫| ƽ| | Դ| ػʵ| ̨ɽ| ǭ| ɽ| | | ҵ| ݳ| ͨ| ޽| ƽ| | | | | Դ| | ǰ| | ˶| | ƽ|