当前位置: 代码迷 >> SQL >> SQL(select)话语优化
  详细解决方案

SQL(select)话语优化

热度:73   发布时间:2016-05-05 14:56:58.0
SQL(select)语句优化
关于 select * from   O1,O2......


至于为何要进行数据库优化,就不在这里重述了。

在做项目的时候,如何最大限度的提高sql的查询效率,应该是大家永远的话题:


在这里,将本着谨慎的,简单的态度,一点一点的讲述sql数据查询语句的优化问题:


一,关于索引:

使用索引的合理性:

条件子句中变量顺序应与索引字键顺序相同。(尽可能在join和order by 的字段上建立索引)将最具有限制性的条件放在前面,大值在前,小值在后。

eg:...where O.a <1000 and O.a>200  效率高于 where O.a>200 and O.a<1000

...where O.a between 200 and 1000 效率高于 where O.a>200 and O.a<1000


二,关于通配符:

避免采用MATCHES和LIKE通配符匹配查询:

由于采用like等通配符查询时,sql优化器实际上还是用顺序搜索的方法来查询的,也就是说,在被查询的字段上建立的索引实际上是不起作用的。

eg:...where O.b <‘12399’ and O.b>‘123000 ’ 效率高于 where O.b matche ‘123*’


三,关于子查询:

查询嵌套层次越多,效率越低,因此应当尽量避免子查询。假如子查询不可避免,那么要在子查询中过滤掉尽可能多的行。

eg:...from O1,O2 where O1.c=O2.c and O2.a=2009 效率高于 from O1 where O1.c in(select O2.c from O2 where O2.a=2009)


四,关于顺序存取时的嵌套查询:

在进行大数据量的索引归类时,有些形式的where子句会强迫优化器使用顺序存取,从而使得原索引字段失效。

eg:...where (O.d = 123 and O.a>200 ) union O.b=1010 效率高于 where (O.d = 123 and O.b>200) or O.b=1010


五,关于临时表:

使用临时表加速查询

把表的一个子集进行排序并创建临时表,有时能加速查询。注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注重不要丢失数据。

eg:...select unique tO1 into temp tO1 "然后(then)"select count(*)from temp tO1 效率高于select count(distinct)


六,关于聚集函数:

1.对于大数据量的求和应避免使用单一的sum命令处理,可采用group by方式与其结合,有时会大大提高效率。

2.避免会引起磁盘读写的 rowid* 等操作。在where子句中或select语句中,用rowid要产生磁盘读写,是一个物理过程,会影响sql性能。



sql优化比较复杂,且受环境限制,但开发过程中,写sql要遵循最起码的原则.如下:
   1.ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.

例如:

(低效)

SELECT … FROM EMP E WHERE SAL > 50000 AND JOB = ‘MANAGER’ AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);

(高效)

SELECT … FROM EMP E WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO) AND SAL > 50000 AND JOB = ‘MANAGER’;
2.SELECT子句中避免使用’*’
   当在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.可是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.

3.   使用表的别名(Alias)

当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.

(Column歧义指的是由于SQL中不同的表具有相同的Column名,当SQL语句中出现这个Column时,SQL解析器无法判断这个Column的归属)

  相关解决方案