欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

oracle sql语句优化编写规范

程序员文章站 2022-03-30 11:46:01
1.对于分区表的查询,原则上必须使用分区键做条件; 2.禁止where子句的左列上使用函数,例如:trunc(create_date) = trunc(sysdate); 原因:这样会使索引失效 3...

1.对于分区表的查询,原则上必须使用分区键做条件;

2.禁止where子句的左列上使用函数,例如:trunc(create_date) = trunc(sysdate);

原因:这样会使索引失效

3.对于关键sql语句,尽量简化,不要包含太多的层次,避免执行计划错误的可能,原则上不能超过2层;

4.sql中尽量少用hint信息,必要时,建议使用hint固定关键sql语句执行计划,原则上批量作业要用hint指定索引;

hint使用方法:oracle用hint方式强制索引

5.对于大表连接的sql语句,由于索引统计信息误差及易导致执行计划错误,为了追求稳定效率,尽可能拆分成多个单表查询的sql语句;

6.sql中对于number型和varchar型的赋值,必须和数据类型保持一致,以避免数据隐形转换时导致sql性能恶化;

7.建议尽量减少in 的使用,对于等值查询使用=替换,如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in,无论哪个表大,用not exists都比not in要快;

8.使用union的时候如果没有混合数据逻辑建议尽量用union all代替;

9.sql中注意like的使用方法,如“%变量%”、“%变量”是用不到索引,“变量%”要注意查询范围, “%”放到越靠后使用索引范围越大;

10.原则上commit 不能单步提交,建议100-1000做一次提交(批量业务事务提交量要作为参数可配,可调,缺省批量事务的提交量应该在100-1000范围内);

11.snapshot too old 错误原则是跟无关,大多是由于select效率低引起;

解释:

snapshot too old 错误是oracle独有的错误,mysql不会出现。

假设你的emp表很大,你在18:00运行

select * from emp;

这个语句的输出结果应该只取决于18:00的时候emp表的数据状态,但事实上,由于emp表很大,你这个语句可能要运行10分钟,然后才看到输出结果

在18:01,有人在emp表上做了一个update,update直接做到表上了,怎样使你18:00运行的select还能看到之前的数据呢?oracle用的是查询前映的办法,即把update之前的数据放到回滚段里保存,使你的select在查询到那个block的时候,会跳转去找前映,这样可以使你的select能正确运行下去。

但可能发生这种情况,就是做update的人commit了,于是前映就有可能在被你的select访问到之前被覆盖,假如真的发生了这种情况,snapshot too old的错误就出现了 ,可以设置undo_retention参数告诉 oracle 要把 undo(回滚数据) 保留多长时间,只要超过你这个查询的时间就不会出现snapshot too old的错误。

12.尽可能使用绑定变量,减少数据库硬解析;尽量少用动态sql ,容易产生大量hard parse并造成library cache pin等待;

13.select语句查询字段不能使用数字常量充当别名;

14.group by 语句如果得到的result set需要sort ,建议加上order by;

15.sql中禁止使用for update;日常维护时必须用select t.*,rowid from tabname t 来替换select * from tabname for update;

16.sql中禁止出现不带任何条件的delete和update语句;

17.维护表和索引时,必须指定表空间;其它具有存储属性的对象也必须指定表空间;

18.应用程序的循环体中打开游标,容易导致超出游标最大数错误;建议将游标移到循环体之外,避免过多重复打开游标;游标使用完后必须关闭游标;

19.原则上sql语句长度不超过4k;

20. 类似的sql语句第一次执行最慢,以后执行速度会加快,因为oracle本身通过sga中的共享池来直接对该sql语句进行缓存,那么在下一次执行类似语句时就直接调用缓存中已解析过的语句。

21. 复杂逻辑结构sql在后台作业中容易出现执行计划的变化,并且不利于后期的优化,尽量将复杂的sql拆分成简单sql,将逻辑控制在应用代码中实现(例如:原本有3层结构的复杂sql,修改成3条简单sql,应用程序控制这3条简单sql的执行逻辑),这样可以固定执行逻辑,固定执行计划。

22. 查询语句尽量少用函数,比如sysdate,而是直接通过应用程序给值,避免每条记录每次都要调用函数。

23. 针对消耗大量cpu(单个操作使用20%以上)和内存(单个操作使用50m以上)操作的计算型sql语句(如avg,sum等),数据库可能会对这类sql语句进行资源限制;建议应用需要的数据抽取出来,通过中间件(或者临时表)将原始数据进行处理计算,如果是临时表的话只抽取必要的数据到临时表,减少表的数据量,提高效率,如果是中间件的话就把计算的任务都给中间件了,减轻了数据库的负担。