SQL语句的优化就是将性能较低的SQL语句转换达成同样目的性能优异的SQL语句
下面我们一起来看看一些可以优化SQL的方法,希望大家多提出意见我们共同学习或者是大家有什么好的优化方法可以提出来共享一下。
第一种优化(使用指定列代替”*”)
使用“*”可以降低编写SQL语句的复杂度,但是却降低了SQL语句执行的效率。
通过SQL语句的执行过程我们来了解SQL语句的执行效率。当一条SQL语句从客户端发送到服务器。ORACLE需要执行以下步骤:
1. 在共享池中搜索SQL语句是否存在。
2. 验证SQL语句的语法是否正确。
3. 执行数据字典来验证表和列的定义。
4. 获取对象的分析锁,以便在语句的分析过程中对象的定义不会被改变。
5. 检查用户是否具有相应的操作权限。
6. 确定语句的最佳执行计划。
7. 将语句和执行方案保存到共享的SQL区
通过上面的第3条我们已经看出来了,如果我们用了“*”替代列的话就会执行我们的第三步,相反如果我们明确的指出了列ORACLE就不会去执行第三个步骤。
下面可以通过测试来看看:
SET TIMING ON
Select * from User
SET TIMING ON
Select user from User
通过上面两条语句的对比我们可以清楚的看出两条语句的执行时间的差别,如果数据较多更为明显。
第二(使用WHERE子句来替代HAVING)
使用HAVING子句过滤分组,也就是在分组之后过滤,因为行分组需要一段时间,所以应该尽量使用WHERE子句过滤行,减少分组的行数,也就减少了分组的时间,从而提高查询效率。
第三(使用“>=”替代“>”|使用“<=”替代“<”)
例如“某列<=8888”和“某列<8889”检索结果是一样的,但是效率并不是一样的。
使用“>=”替代“>”|使用“<=”替代“<”
上面两个运算的区别在于,如果使用“某列<8889”则ORACLE会定位到8889,然后再去找比8889小的数据,如果使用“某列<=8888”,则ORACLE直接定位到等于8888的数。虽然这种优化显得差别不大,但是在查询数据量特别大的时候,尤其再循环语句中使用比较操作的时候区别就会很明显了。
第四(使用EXISTS替代IN和替代DISTINCT)
1. 使用EXISTS替代IN
我们使用IN操作符是用来检查一个值是否包含在列表中。EXISTS和IN不同,EXISTS只检查行的存在性,而IN检查的是实际的值。相应的我们使用NOT EXISTS来替代NOT IN
来提高查询的效率。
2. 使用EXISTS替代DISTINCT
在连接查询的SQL语句当中,我们使用DISTINCT关键字来过禁止重复行的显示。尽量使用EXISTS替代DISTINCT。使用EXISTS用于检查子查询返回行的存在性,因为DISTINCT在禁止重复行显示之前要排序检索到的行。(这一步非常的消耗时间)
第五(表连接查询)
1.表查询
在执行每条查询语句的时候,ORACLE内部要执行许多的工作,比如:解析SQL语句、估算索引利用率、绑定变量、以及读取数据块等,因此我们要减少访问SQL的次数。主要就是指我们可以通过一次查询获取数据就尽量不要通过两次或多次来查询。
2.FROM子句表中的顺序
在SELECT语句的FROM子句中我们可以指定多个表,至于表和表之间的先后顺序,如果光是从查询结果来看,哪个表放在前面都是一样的,但是要从执行的效率来考虑表之间的顺序就要我们考虑的问题了。
ORACLE的解析器在处理FROM子句的中的表时,是按照从左到右的顺序扫描的。也就是说FROM子句的最后指定的表现被处理。ORACLE将它视为驱动表(Driving table)并对该表进行排序,然后再扫描倒数的第二个表。最后将第二个表中检索出来的顺序和第一个表的合适记录做合并。因此我们建议采用比较小的表来做驱动表,也就是放到FROM子句的最后。
例如:有两张表T1(888条)和T2(88888条)我们应该这样写
Select 列名 from T2,T1
3.WHERE子句的连接顺序
ORACLE采用自右至左(自下向上)的顺序解析WHERE子句,根据这个顺序,表之间的连接应该写在WHERE条件之前,将可以过滤最大数量记录的条件写在WHERE末尾。