PS: 如Where 有使用到 Subquery 尽量改写为虚拟 Table
低效:
1. SELECT .... 2. FROM Table1,Table2,Table3 3. whereTable1=条件一 4. andTable2=条件二 5. and table2 =(select..... 6. fromTable4 7. where条件四) 8. and table3=table2 9. and table2=table1高效:
1. SELECT .... 2. FROM Table1,Table2,(select..... 3. fromTable3,Table4 4. where条件四 5. andTable3=Table4)Table3 6. whereTable1=条件一 7. andTable2=条件二 8. and table3=table2 9. and table2=table1(1) 低效:
1. SELECT … 2. FROM DEPT 3. WHERE SAL *12>25000;高效:
1. SELECT … 2. FROM DEPT 3. WHERE SAL >25000/12;(2) 高效:
1. SELECT * 2. FROM EMP 3. WHERE DEPTNO >=4低效:
1. SELECT * 2. FROM EMP 3. WHERE DEPTNO >3(3) 高效:
1. SELECT LOC_ID , LOC_DESC , REGION 2. FROM LOCATION 3. WHERE LOC_ID =10 4. UNION 5. SELECT LOC_ID , LOC_DESC , REGION 6. FROM LOCATION 7. WHERE REGION ='MELBOURNE'低效:
1. SELECT LOC_ID , LOC_DESC , REGION 2. FROM LOCATION 3. WHERE LOC_ID =10 OR REGION ='MELBOURNE'(4) 低效: (索引失效)
1. SELECT … 2. FROM DEPARTMENT 3. WHERE DEPT_CODE IS NOT NULL;高效: (索引有效)
1. SELECT … 2. FROM DEPARTMENT 3. WHERE DEPT_CODE >=0;不使用索引:
1. SELECT ACCOUNT_NAME 2. FROM TRANSACTION 3. WHERE AMOUNT !=0;使用索引:
1. SELECT ACCOUNT_NAME 2. FROM TRANSACTION 3. WHERE AMOUNT >0;(5) 低效:执行约156.3秒
1. SELECT … 2. FROM EMP E 3. WHERE SAL >50000 4. AND JOB ='MANAGER' 5. AND 25<(SELECT COUNT(*) FROM EMP 6. WHERE MGR=E.EMPNO);高效:执行约10.6秒
1. SELECT … 2. FROM EMP E 3. WHERE 25<(SELECT COUNT(*) FROM EMP 4. WHERE MGR=E.EMPNO) 5. AND SAL >50000 6. AND JOB ='MANAGER';(6) 使用DECODE函数来减少处理时间 使用DECODE函数可以避免重复描述相同记录或重复连结相同的表 例如:
1. SELECT COUNT(*),SUM(SAL) 2. FROM EMP 3. WHERE DEPT_NO =0020 4. AND ENAME LIKE 'SMITH%'; 5. 6. SELECT COUNT(*),SUM(SAL) 7. FROM EMP 8. WHERE DEPT_NO =0030 9. AND ENAME LIKE 'SMITH%';你可以用DECODE函数更高效
1. SELECT COUNT(DECODE(DEPT_NO,0020,'X',NULL)) D0020_COUNT, 2. COUNT(DECODE(DEPT_NO,0030,'X',NULL)) D0030_COUNT, 3. SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL, 4. SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL 5. FROM EMP 6. WHERE ENAME LIKE 'SMITH%';· 使用日期
当使用日期时,需要注意如果有超过5位小数加到日期上,这个日期会到下一天 例如:
1. SELECT TO_DATE('01-JAN-93'+.99999) 2. FROM DUAL; 3. Returns: 4. '01-JAN-93 23:59:59' 1. SELECT TO_DATE('01-JAN-93'+.999999) 2. FROM DUAL; 3. Returns: 4. '02-JAN-93 00:00:00'· 以笔数多的放在前面
表 TAB1 16,384 笔,表 TAB2 1 笔 选择TAB2作为基础表 (最好的方法)
1. select count(*)from tab1,tab2执行约0.96秒
选择TAB2作为基础表 (不佳的方法)
1. select count(*)from tab2,tab1执行约26.09秒
· 不同表的效能
原表
1. SELECT NAME 2. FROM EMP 3. WHERE EMP_NO =1234; 4. SELECT NAME 5. FROM DPT 6. WHERE DPT_NO =10; 7. SELECT NAME 8. FROM CAT 9. WHERE CAT_TYPE ='RD';高效
1. SELECT E.NAME,D.NAME,C.NAME 2. FROM CAT C,DPT D,EMP E,DUAL X 3. WHERE NVL('X',X.DUMMY)= NVL('X',E.ROWID(+)) 4. AND NVL('X',X.DUMMY)= NVL('X',D.ROWID(+)) 5. AND NVL('X',X.DUMMY)= NVL('X',C.ROWID(+)) 6. AND E.EMP_NO(+)=1234 7. AND D.DEPT_NO(+)=10 8. AND C.CAT_TYPE(+)='RD';缺点程序可携性低
· 删除重覆记录
1. DELETE FROM EMP E 2. WHERE E.ROWID >(SELECT MIN(X.ROWID) 3. FROM EMP X 4. WHERE X.EMP_NO = E.EMP_NO);· 减少对表的查询
低效
1. SELECT TAB_NAME 2. FROM TABLES 3. WHERE TAB_NAME = 4. (SELECT TAB_NAME 5. FROM TAB_COLUMNS 6. WHERE VERSION =604) 7. AND DB_VER= 8. (SELECT DB_VER 9. FROM TAB_COLUMNS 10. WHERE VERSION =604)高效
1. SELECT TAB_NAME 2. FROM TABLES 3. WHERE (TAB_NAME, 4. DB_VER)= 5. (SELECT TAB_NAME, 6. DB_VER) 7. FROM TAB_COLUMNS WHEREVERSION =604)· Update 多Column 例子:
低效:
1. UPDATE EMP 2. SET EMP_CAT = 3. (SELECT MAX(CATEGORY) 4. FROM EMP_CATEGORIES), 5. SAL_RANGE = 6. (SELECT MAX(SAL_RANGE) 7. FROM EMP_CATEGORIES) 8. WHERE EMP_DEPT =0020;高效:
1. UPDATE EMP 2. SET (EMP_CAT, 3. SAL_RANGE)= 4. (SELECT MAX(CATEGORY), 5. MAX(SAL_RANGE) 6. FROM EMP_CATEGORIES) 7. WHERE EMP_DEPT =0020; · 使用EXISTS(或NOT EXISTS)通常能提高查询的效率.低效:
1. SELECT * 2. FROM EMP 3. WHERE EMPNO >0 4. AND DEPTNO IN 5. (SELECT DEPTNO 6. FROM DEPT 7. WHERE LOC ='MELB')高效:
1. SELECT * 2. FROM EMP 3. WHERE EMPNO >0 4. AND EXISTS 5. (SELECT 'X' 6. FROM DEPT 7. WHERE DEPT.DEPTNO = EMP.DEPTNO 8. AND LOC ='MELB')· 用NOT EXISTS替代NOT IN,为了避免使用NOT IN ,我们可以把它改成外部连接(Outer Joins)或NOT EXISTS.
例如:
1. SELECT … 2. FROM EMP 3. WHERE DEPT_NO NOT IN 4. (SELECT DEPT_NO 5. FROM DEPT 6. WHERE DEPT_CAT='A');(方法一: 高效)
1. SELECT …. 2. FROM EMP A, 3. DEPT B 4. WHERE A.DEPT_NO = B.DEPT(+) 5. AND B.DEPT_NO IS NULL 6. AND B.DEPT_CAT(+)='A'(方法二: 最高效)
1. SELECT …. 2. FROM EMP E 3. WHERE NOT EXISTS 4. (SELECT 'X' 5. FROM DEPT D 6. WHERE D.DEPT_NO = E.DEPT_NO 7. AND DEPT_CAT ='A');· 用EXISTS替代DISTINCT
低效:
1. SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPTD,EMP E 2. WHERE D.DEPT_NO = E.DEPT_NO高效:
1. SELECT DEPT_NO,DEPT_NAME FROM DEPTD 2. WHERE EXISTS ( SELECT ‘X’ FROM EMP E 3. WHERE E.DEPT_NO = D.DEPT_NO);· 计算目前执行SQL的效能状况,以下为找出最低效的SQL
1. SELECT EXECUTIONS, 2. DISK_READS, 3. BUFFER_GETS, 4. ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2)Hit_radio, 5. ROUND(DISK_READS/EXECUTIONS,2)Reads_per_run, 6. SQL_TEXT 7. FROM V$SQLAREA 8. WHERE EXECUTIONS>0 9. AND BUFFER_GETS >0 10. AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS <0.8 11. ORDER BY 4 DESC;· Outer Join 外部连接
1. select d.deptname, e.ename from dept d, emp e where d.empno *= e.enum;
2. select d.deptname,e.ename from dept d, emp e where d.empno = e.enum(+);
· 检查 table 或 view 是否存在于 Oracle
1. SELECT COUNT (TABLE_NAME) 2. FROM all_tables 3. WHERE UPPER (TABLE_NAME)= UPPER ('PathologyTest') 4. SELECT COUNT (view_name) 5. FROM all_views WHEREUPPER (view_name)= UPPER ('v_PathologyTest') ---来自腾讯云社区的---聚沙成塔
微信扫一扫打赏
支付宝扫一扫打赏