1.单条SQL长度不宜超过100行
select sql_id,count(*) from v$sqltext group by sql_id having count(*)>=100 order by count(*) desc;
2、SQL子查询嵌套不易超过3层
一般来说,子查询嵌套如果超过3层,容易导致SQL语句的解析过于复杂,导致产生错误的执行计划。此外子查询嵌套过多,一般适宜分解成更简单的多条SQL。
3、SQL表关联需考虑连接和限制条件的索引
create table t as select * from v$sql_plan;
select * from t where sql_id not in (
select sql_id from t where sql_id in(
select sql_id from t where operation='NESTED LOOPS')
and (opreation like '%INDEX%' or object_owner like '%SYS%'))
and sql_id in (select sql_id from t where sql_id in(select sql_id from t where opreation='NESTED LOOPS'));
-------------使用Nested Loops Join 但是没有用到索引的情况----------------------------------------
4、尽量避免HINT在代码中出现
select sql_text,sql_id,module,t.service,first_load_time,last_load_time,executions
from v$sql t where sql_text like '%/*+%' and t.service not like 'SYS$%';
-------------非SYS用户用HINT的所有SQL---------------------------------
5、尽量使用批量提交
未使用批量提交一般,一般都是因为将commit写到循环内
select t1.sid,t1.value,t2.name from v$sesstat t1,v$statname t2 where t2.name like '%user commit%'
and t1.statistic#=t2.statistic# and value>=10000 order by value desc;
---------------查询提交次数过多的session----------------------------------
6、同一过程包中出现重复逻辑块需要封装,统一调用,否则修改统一逻辑,代码可能需要修改多处,不利于维护
7、同一SQL模块避免出现大量相似之处,造成数据泥潭和重复代码
8、外键未建索引将引发死锁及影响表连接性能
9、建联合索引需谨慎
(1)要结合单列查询考虑,决定前缀
将单独查询较多的列作为组合索引前缀,如col1单独查询多,组合索引col1,col2好过col2,col1的索引组合
(2)范围索引查询影响组合索引
组合索引中,如果有等值条件的范围条件组合情况下,等值条件在前,性能更好
where col1=2 and col2>100 and col2<200,此时col1,col2组合索引性能高于col2,col1的索引组合
(3)需要考虑回表因素
一般情况下,如果建索引可以避免回表(在索引中即可完成检测),也可以考虑对多列建组合索引,一般组合索引列不宜超过4个,
否则维护索引和更新会造成严重性能问题