前言
一:常规SQL语句优化
1:建议 不用 * 来替代所有列名
2:用 truncate 替代 delete
示例:创建一个存储过程,实现使用 truncate 命令动态删除数据表。
1 SYS@orcl> create or replace procedure trun_table(table_deleted in varchar2) as --创建一个存储过程,传入一个表示表名称的参数,实现清空指定的表 2 2 cur_name integer;--定义内部变量,存储打开的游标 3 3 begin 4 4 cur_name := dbms_sql.open_cursor;--打开游标 5 5 dbms_sql.parse(cur_name,'truncate table'||table_deleted ||'drop storage',dbms_sql.native);--执行truncate table tb_name命令,从而实现清空指定的表 6 6 dbms_sql.close_cursor(cur_name);--关闭游标 7 7 exception 8 8 when others then dbms_sql.close_cursor(cur_name);--出现异常,关闭游标 9 9 raise; 10 10 end trun_table; 11 11 / 12 13 Procedure created. 14 15 SYS@orcl>
3:在确保完整性的情况下多使用 commit 语句
4:尽量减少表的查询次数
在含有子查询的sql语句中,要特别注意减少对表的查询。
- 1:低效率的SQL查询语句
1 SCOTT@orcl> select empno,ename,job from emp where deptno in(select deptno from dept where loc='BEIJING') OR DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOC='NEW YORK'); 2 3 no rows selected 4
- 2:对上面的代码进行适当的修改。高效率的SQL查询语句如下:
1 2 3 SCOTT@orcl> select empno,ename,job from emp where deptno in(select deptno from dept where loc='BEIJING' OR LOC='NEW YORK'); 4 5 no rows selected 6 7 SCOTT@orcl>
5: 用 [not] exists 替代 【not】 in
1 :低效率的 not in 子句
1 SCOTT@orcl> select empno,ename from emp where deptno not in (select deptno from dept where loc='BEIJING'); 2 3 EMPNO ENAME 4 ---------- ---------- 5 9527 EAST 6 7934 MILLER 7 7839 KING 8 7782 CLARK 9 8889 dfadf 10 7900 JAMES 11 7844 TURNER 12 7698 BLAKE 13 7654 MARTIN 14 7521 WARD 15 7499 ALLEN 16 17 EMPNO ENAME 18 ---------- ---------- 19 7902 FORD 20 7876 ADAMS 21 7788 SCOTT 22 7566 JONES 23 7369 SMITH 24 25 16 rows selected. 26 27 SCOTT@orcl>
2:高效的exists 子句
1 2 SCOTT@orcl> select empno,ename from emp where exists (select deptno from dept where loc !='BEIJING'); 3 4 EMPNO ENAME 5 ---------- ---------- 6 9527 EAST 7 8889 dfadf 8 7369 SMITH 9 7499 ALLEN 10 7521 WARD 11 7566 JONES 12 7654 MARTIN 13 7698 BLAKE 14 7782 CLARK 15 7788 SCOTT 16 7839 KING 17 18 EMPNO ENAME 19 ---------- ---------- 20 7844 TURNER 21 7876 ADAMS 22 7900 JAMES 23 7902 FORD 24 7934 MILLER 25 26 16 rows selected. 27 28 SCOTT@orcl>
二:表链接优化
1:驱动表的选择
2:where 子句的链接顺序
三:合理使用索引
1:何时使用索引
2:索引列和表达式的选择
3:选择复合索引主列
示例:为tb_test 表创建 一个复合索引complex_inde 该索引包括 column1、column2、column3个列。
4:避免全表扫描大表
5:监视索引是否被使用
示例:监视学生成绩表 studentgrade 的grade_index是否被使用。
- 1:设置监视索引 grade_index :
1 SCOTT@orcl> desc studentgrade; 2 Name Null? Type 3 ----------------------------------------- -------- ---------------------------- 4 ID NOT NULL NUMBER 5 NAME VARCHAR2(10) 6 SUBJECT VARCHAR2(10) 7 GRADE NUMBER 8 9 SCOTT@orcl> alter index grade_index monitoring usage; 10 11 Index altered. 12 13 SCOTT@orcl>
- 2 检查索引使用情况
1 2 SCOTT@orcl> select * from v$object_usage; 3 4 INDEX_NAME TABLE_NAME MON USE 5 ------------------------------ ------------------------------ --- --- 6 START_MONITORING END_MONITORING 7 ------------------- ------------------- 8 GRADE_INDEX STUDENTGRADE YES NO 9 03/27/2018 22:28:19 10 11 12 SCOTT@orcl>
- 3 在第二步的检测中,如果发现索引grade_index 在限定时间内得不到使用(即:used列的值为NO)则建议使用drop index 语句删除;