Oracle之sql语句优化

项目中虽然使用了orm映射,但Oracle系统的优化还是很有价值的,这里从sql语句的角度对常用的语句做下总结。

1、from字段中的优化:

Oracle安照从右到左的顺序加载表数据,应该把可以排除数据最多的表放到后面(基础表)。

比如,在关联查询中,把课程表放到后面,成绩表放到前面,因为课程表数据一般比较少,关联的时候可以快速的过滤掉一些成绩数据。

2、where中的优化:

对可以过滤数据最多的,放到后面,原理也是Oracle执行从下到上(从右到左)的顺序。

3、使用列名替代*:

省去从字典表中解析的过程 :

Oracle执行sql语句过程:

在共享池中搜索sql语句是否已经存在

验证sql是否语法精确

执行数据字典验证表和列的定义

获取对象的分析锁,以便在语句的分析过程中对象的定义不会改变

检查用户是否具有相应的操作权限

确定语句最佳执行计划

将语句和执行方案保存到共享的sql区。

4、使用?参数形式:

尽量不要使用拼接字串的方式,因为带有?的参数形式会缓存分析结果,省去上面很多步骤。

5、使用decode函数:

decode不会重复扫描相同记录或重复连接相同的表,减少表的扫描次数。

6、使用truncate替代delete:

delete:逐条删除,并保存回滚还原点。DML(数据操作语言insert,update,delete,merge)

truncate不会保存回滚点,是DDL(数据定义语言,如drop,alter)

在oracle里DML是可以rollback的,而DDL是不可以的

如果数据量大,差别很大的。

7、尽量多用commit:

Oracle只有在commit后才会提交(区别于sqlserver),如果没有提交,会在内存中保存很多数据。commit后释放的资源有:

回滚上段用于恢复数据库的记录信息

被程序语句获得的锁

Redo log buffer中的空间

为管理上述3种资源的内部花费

8、使用where语句替代having子句:

在分组或者配合group的时候会使用having。

where会直接过滤掉数据,使用having往往会配合group,检索出数据后,会带着数据进行排序、统计等。

9、on/where/having排序使用顺序:

on:做的是数据映射,在映射时,把没用的数据直接过滤掉了

where:先进行一个全表的搜索,之后再进行数据筛选

where又比having要快,having中带的垃圾数据同样也做了运算

10、减少对表的查询:

在含有子查询的sql语句中,要特别注意减少对表的查询。

Select tab_name from tables where (tab_name,db_ver)=(select tab_name,db_ver from tab_columns where version=604)

11、使用表别名:

减少对sql语句解析的时间并减少由多个表相同的Column名歧义引起的语法错误

如果不使用别名,会去字典表中查找,判断是否有列名歧义。

12、使用exists替代in not exists替代not in:

Oracle采用命中即返回的方式,在多表链接查询时,如果使用in会导致子查询的表全表遍历,并排序、合并,这时候可以使用外链接或not  exists 替代。

13、识别低效率执行的语句:

各种sql优化的图形工具层出不穷,但可以写出自己的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;

14、使用索引:

使用于查询的表,提供了主键的唯一性验证,long或者long raw数据类型,几乎可以索引所有列

定期重建索引,在删除和修改多的表,不适用索引,原因,不解释了。

注意,并不是创建了索引后就一定会走索引,使用索引的时候,不能使用索引进行一些计算,否则失效

使用索引快于全表扫描,在多表连接使用索引提高效率。

避免在索引上使用not:

会停止索引(not表示的是:没有什么, 而索引表示的是:有什么)

用exitsts替代distinct:

在提交一个包含一对多表信息(部门和雇员表)的查询时使用。原因:查找即返回原理

避免在索引列上使用计算:

低效:

Select * from dept  where sal * 12 >25000

高效:

Select * from dept where sal> 25000/12

避免在索引列上使用is null 和 is not null:

因为索引不会对null数据类型进行索引,索引只是记录有什么

对于单列索引,不会进行索引

对于符合索引,如果所有列多为空,不进行索引,只要有一个列不空,就索引。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/c6a4b7a2dd08b3c0f58e1c5e7f5cd02f.html