SELECT JOB,AVG(AGE) FROM TEMP
GROUP BY JOB HAVING JOB = 'STUDENT' OR JOB = 'MANAGER';
高效:
SELECT JOB,AVG(AGE) FROM EMP
WHERE JOB = 'STUDENT' OR JOB = 'MANAGER' GROUP BY JOB;
13、根据需要用UNION ALL替换UNION:
当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并,
然后在输出最终结果前进行排序。如果用UNION ALL替代UNION, 这样排序就不是必要了。
效率就会因此得到提高。需要注意UNION ALL将重复输出两个结果集合中相同记录。因此要
从业务需求使用UNION ALL的可行性。UNION 将对结果集合排序,这个操作会使用到
SORT_AREA_SIZE这块内存。对于这块内存的优化也很重要。
低效:
SELECT USER_ID,BILL_ID FROM USER_TAB1 WHERE AGE = '20'
UNION
SELECT USER_ID,BILL_ID FROM USER_TAB2 WHERE AGE = '20';
高效:
SELECT USER_ID,BILL_ID FROM USER_TAB1 WHERE AGE = '20'
UNION ALL
SELECT USER_ID,BILL_ID FROM USER_TAB2 WHERE AGE = '20';
14、用EXISTS替换DISTINCT:
SELECT DISTINCT USER_ID,BILL_ID FROM USER_TAB1 D,USER_TAB2 E
WHERE D.USER_ID= E.USER_ID;
(高效):
SELECT USER_ID,BILL_ID FROM USER_TAB1 D WHERE EXISTS(SELECT 1
FROM USER_TAB2 E WHERE E.USER_ID= D.USER_ID);
15、尽量多使用COMMIT:
USER_ID PK NOT NULL
USER_DESC NOT NULL
USER_TYPE NULL
低效: (索引不被使用)
SELECT USER_ID FROM USER_TAB ORDER BY USER_TYPE;
高效: (使用索引)
SELECT USER_ID FROM USER_TAB WHERE USER_TYPE> 0;
28、避免改变索引列的类型:
当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换。
假设 USER_ID 是一个数值类型的索引列。
SELECT … FROM USER_TAB WHERE USER_ID = '123';
实际上,经过ORACLE类型转换, 语句转化为:
SELECT … FROM USER_TAB WHERE USER_ID = TO_NUMBER('123');
幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变。
现在,假设USER_TYPE是一个字符类型的索引列。
SELECT … FROM USER_TAB WHERE USER_TYPE = 123 ;
这个语句被ORACLE转换为:
SELECT … FROM USER_TAB WHERE TO_NUMBER(USER_TYPE)=123;
因为内部发生的类型转换, 这个索引将不会被用到! 为了避免ORACLE对你的SQL进行隐式的类
型转换, 最好把类型转换用显式表现出来。
注:当字符和数值比较时, ORACLE会优先转换数值类型到字符类型。
SELECT … FROM USER_TAB WHERE TO_NUMBER(USER_TYPE)=123;
29、WHERE子句:
某些SELECT 语句中的WHERE子句不使用索引。
(1)'!='不走索引。索引只能告诉我们什么存在于表中, 而不能告诉你什么不在表中。
(2)'||'是字符连接函数。就象其他函数那样, 停用了索引。
(3)'+'是数学函数。和其他数学函数一样, 停用了索引。
(4)相同的索引列不能互相比较,这将会启用全表扫描。
30、 a.如果检索数据量超过30%的表中记录数,使用索引将没有显著的效率提高。
b.在特定情况下,使用索引也许会比全表扫描更慢,但这是同一个数量级上的区别。
而通常情况下,使用索引比全表扫描要块几倍乃至几千倍。
31、查'低效执行'的SQL语句:
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;