oracle sql性能2(三)

2014-11-24 16:56:17 · 作者: · 浏览: 5
----------- 0 recursive calls 0 db block gets 143 consistent gets 0 physical reads 0 redo size 63749 bytes sent via SQL*Net to client 7751 bytes received via SQL*Net from client 68 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1003 rows processed SQL> select * from unionvsor /*3rd test*/ 2 where a = 1003 3 union 4 select * from unionvsor 5 where b = 1; 1003 rows selected. Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 SORT (UNIQUE) 2 1 UNION-ALL 3 2 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR' 4 3 INDEX (RANGE SCAN) OF 'UA' (NON-UNIQUE) 5 2 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR' 6 5 INDEX (RANGE SCAN) OF 'UB' (NON-UNIQUE) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 10 consistent gets 0 physical reads 0 redo size 63735 bytes sent via SQL*Net to client 7751 bytes received via SQL*Net from client 68 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 1003 rows processed 用UNION的效果可以从consistent gets和 SQL*NET的数据交换量的减少看出 37用IN来替换OR 下面的查询可以被更有效率的语句替换: 低效: 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);

译者按:
这是一条简单易记的规则,但是实际的执行效果还须检验,在ORACLE8i下,两者的执行路径似乎是相同的. 
38避免在索引列上使用IS NULL和IS NOT NULL
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引 .对于单列索引,如果列包含空值,索引中将不存在此记录. 对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空,则记录存在于索引中.
举例:
如果唯一性索引建立在表的A列和B列上, 并且表中存在一条记录的A,B值为(123,null) , ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入). 然而如果
所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空. 因此你可以插入1000
条具有相同键值的记录,当然它们都是空!
因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引.
举例: 
  
低效: (索引失效) 
SELECT … 
FROM DEPARTMENT 
WHERE DEPT_CODE IS NOT NULL; 
  
高效: (索引有效) 
SELECT … 
FROM DEPARTMENT 
WHERE DEPT_CODE >=0; 
39总是使用索引的第一个列 
如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引.  
  
译者按: 
这也是一条简单而重要的规则. 见以下实例. 
  
SQL> create table multiindexusage ( inda number , indb number , descr varchar2(10)); 
Table created. 
SQL> create index multindex on multiindexusage(inda,indb); 
Index created. 
SQL> set autotrace traceonly 
  
SQL>  select * from  multiindexusage where inda = 1; 
Execution Plan 
---------------------------------------------------------- 
    0      SELECT STATEMENT Optimizer=CHOOSE 
    1    0   TABLE ACCESS (BY INDEX ROWID) OF 'MULTIINDEXUSAGE' 
    2    1     INDEX (RANGE SCAN) OF 'MULTINDEX' (NON-UNIQUE) 
  
SQL> select * from  multiindexusage where indb = 1; 
Execution Plan 
---------------------------------------------------------- 
    0      SELECT STATEMENT Optimizer=CHOOSE 
    1    0   TABLE ACCESS (FULL) OF 'MULTIINDEXUSAGE' 
     
很明显, 当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引 
  
40ORACLE内部操作 
当执行查询时,ORACLE采用了内部的操作. 下表显示了几种重要的内部操作. 
ORACLE Clause  内部操作 
ORDER BY  SORT ORDER BY 
UNION  UNION-ALL 
MINUS  MINUS 
INTERSECT  INTERSECT 
DISTINCT,MINUS,INTERSECT,UNION  SORT UNIQUE 
MIN,MAX,COUNT  SORT AGGREGATE 
GROUP BY  SORT GROUP BY 
ROWNUM  COUNT or COUNT STOPKEY 
Queries involving Joins  SORT JOIN,MERGE JOIN,NESTED LOOPS 
CONNECT BY  CONNECT BY 

41用UNION-ALL 替换UNION ( 如果有可能的话)
当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序.
如果用UNION ALL替代UNION, 这样排