秦鹏飞的专栏

关于SQL语句优化方法

有些是通用的(如避免Select *);

有些不同的数据库管理系统有所区别(如Where子句顺序);

然后必须根据实际环境进行调优,因为即使是相同的数据库和表,在数据量或其他环境变化之后,SQL效率可能是不同的。所以,优化不是一蹴而就的。

一些总结避免Select *

Selcet中每少提取一个字段,数据的提取速度就会有相应的提升。提升的速度还要看您舍弃的字段的大小来判断。应避免使用Select *。

表关联顺序

Oracle的解析器按照从右到左的顺序处理from子句中的表名,from子句中写在最后的表(基础表 driving table)将被最先处理,在from子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表。

WHERE子句中的顺序

Oracle采用自下而上的顺序解析Where子句,根据这个原理,表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾。

避免全表扫描

Where中少用NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE,它们会引起全表扫描。

用Where子句替代having子句

避免使用having子句,having只会在检索出所有记录之后才对结果集进行过滤。

exists代替in

Oracle中In子查询返回的结果不能超过1000条,使用exists为替代方案。

性能测试

目的

我在客户端中执行如下语句,通过改变表关联顺序、where条件顺序,查看所用时间的变化。可能换个环境,得出的结果会大不相同,请以实际环境为准哦。

数据库环境

表关联顺序自连接

小表在前,DB2用时:0.015sORACLE用时:0.329s

select count(*) from TableB b,TableA aWHERE b.ID=a.ID

select count(*) from TableA a,TableB b WHERE a.ID=b.ID

可以看到,DB2下时间变化不大,Oracle相差2倍。

左连接

小表在前,DB2用时:0.453sORACLE用时:0.047s

select count(*)from TableB bLEFT JOIN TableA a ON b.ID=a.ID

大表在前,DB2用时:0.031sORACLE用时:0.031s

select count(*)from TableA aLEFT JOIN TableB b ON a.ID=b.ID

可以看到,,DB2下用时相差10倍以上,Oracle下变化不大。

内连接

小表在前,DB2用时:0.078sORACLE用时:0.015s

select count(*)from TableB bINNER JOIN TableA a ON b.ID=a.ID

大表在前,DB2用时:0.016sORACLE用时:0.016s

select count(*)from TableA aINNER JOIN TableB b ON a.ID=b.ID

可以看到,DB2下用时相差4倍,Oracle下变化不大。

WHERE条件顺序

过滤条件在右,DB2用时:0.109sORACLE用时:0.015s

select count(*)from TableB b,TableA a

过滤条件在左,DB2用时:0.156sORACLE用时:0.016s

select count(*)from TableB b,TableA ab.ID=a.ID

DB2用时变化1/3,当条件比较多,数据量比较大时,会更加明显。

孤独是一种无奈的选择,孤独是因为没有找到合适的同行者,

秦鹏飞的专栏

相关文章:

你感兴趣的文章:

标签云: