要提高SQL语句的执行效率,最常见的方法就是建立索引,以及尽量避免全表扫描。在本章MySQL教程中,UncleToo给大家整理一些常见的SQL优化技巧,避免全表扫描。一个简单的优化,也许能让你的SQL执行效率提高几倍,甚至几十倍。
1、避免在where子句中使用 is null 或 is not null 对字段进行判断。
如:
select id from table where name is null
在这个查询中,就算我们为 name 字段设置了索引,查询分析器也不会使用,因此查询效率底下。为了避免这样的查询,在数据库设计的时候,尽量将可能会出现 null 值的字段设置默认值,这里如果我们将 name 字段的默认值设置为0,那么我们就可以这样查询:
select id from table where name = 0
如:
select name from table where id <> 0
数据库在查询时,对 != 或 <> 操作符不会使用索引,而对于 < 、 <= 、 = 、 > 、 >= 、 BETWEEN AND,数据库才会使用索引。因此对于上面的查询,正确写法应该是:
select name from table where id < 0
union all
select name from table where id > 0
4、少用 in 或 not in。
虽然对于 in 的条件会使用索引,不会全表扫描,但是在某些特定的情况,使用其他方法也许效果更好。如:
select name from table where id in(1,2,3,4,5)
像这种连续的数值,我们可以使用 BETWEEN AND,如:
select name from table where id between 1 and 5
5、注意 like 中通配符的使用。
下面的语句会导致全表扫描,尽量少用。如:
select id from table where name like'%UncleToo%'
或者
select id from table where name like'%UncleToo'
而下面的语句执行效率要快的多,因为它使用了索引:
select id from table where name like'UncleToo%'
6、避免在 where 子句中对字段进行表达式操作。
如:
select name from table where id/2 = 100
正确的写法应该是:
select name from table where id = 100*2
7、避免在 where 子句中对字段进行函数操作。
如:
select id from table where substring(name,1,8) = 'UncleToo'
或
select id from table where datediff(day,datefield,'2014-07-17') >= 0
这两条语句中都对字段进行了函数处理,这样就是的查询分析器放弃了索引的使用。正确的写法是这样的:
select id from table where name like'UncleToo%'
或
select id from table where datefield <= '2014-07-17'
也就是说,不要在 where 子句中的 = 左边进行函数、算术运算或其他表达式运算。
8、在子查询中,用 exists 代替 in 是一个好的选择。
如:
select name from a where id in(select id from b)
如果我们将这条语句换成下面的写法:
select name from a where exists(select 1 from b where id = a.id)
这样,查询出来的结果一样,但是下面这条语句查询的速度要快的多。
1、避免在where子句中使用 is null 或 is not null 对字段进行判断。
如:
select id from table where name is null
在这个查询中,就算我们为 name 字段设置了索引,查询分析器也不会使用,因此查询效率底下。为了避免这样的查询,在数据库设计的时候,尽量将可能会出现 null 值的字段设置默认值,这里如果我们将 name 字段的默认值设置为0,那么我们就可以这样查询:
select id from table where name = 0
2、避免在 where 子句中使用 or来链接条件。
如:
select id from table where name = 'UncleToo' or name = 'PHP'
这种情况,我们可以这样写:
select id from table where name = 'UncleToo'
union all
select id from table where name = 'PHP'
如:
select name from table where id <> 0
数据库在查询时,对 != 或 <> 操作符不会使用索引,而对于 < 、 <= 、 = 、 > 、 >= 、 BETWEEN AND,数据库才会使用索引。因此对于上面的查询,正确写法应该是:
select name from table where id < 0
union all
select name from table where id > 0
4、少用 in 或 not in。
虽然对于 in 的条件会使用索引,不会全表扫描,但是在某些特定的情况,使用其他方法也许效果更好。如:
select name from table where id in(1,2,3,4,5)
像这种连续的数值,我们可以使用 BETWEEN AND,如:
select name from table where id between 1 and 5
5、注意 like 中通配符的使用。
下面的语句会导致全表扫描,尽量少用。如:
select id from table where name like'%UncleToo%'
或者
select id from table where name like'%UncleToo'
而下面的语句执行效率要快的多,因为它使用了索引:
select id from table where name like'UncleToo%'
6、避免在 where 子句中对字段进行表达式操作。
如:
select name from table where id/2 = 100
正确的写法应该是:
select name from table where id = 100*2
7、避免在 where 子句中对字段进行函数操作。
如:
select id from table where substring(name,1,8) = 'UncleToo'
或
select id from table where datediff(day,datefield,'2014-07-17') >= 0
这两条语句中都对字段进行了函数处理,这样就是的查询分析器放弃了索引的使用。正确的写法是这样的:
select id from table where name like'UncleToo%'
或
select id from table where datefield <= '2014-07-17'
也就是说,不要在 where 子句中的 = 左边进行函数、算术运算或其他表达式运算。
8、在子查询中,用 exists 代替 in 是一个好的选择。
如:
select name from a where id in(select id from b)
如果我们将这条语句换成下面的写法:
select name from a where exists(select 1 from b where id = a.id)
这样,查询出来的结果一样,但是下面这条语句查询的速度要快的多。