MySQL中的SQL常见调优策略测试

在项目中,SQL的调优对项目的性能来讲至关重要,所有掌握常见的SQL调优方式是必不可少的,下面介绍几种常见的SQL的调优方式,供借鉴.

explain的type:

表示MySQL在表中找到所需行的方式,又称“访问类型”。

常用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

index: Full Index Scan,index与ALL区别为index类型只遍历索引树

range:只检索给定范围的行,使用一个索引来选择行

ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

1.避免全表扫描

对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

explain select * from test1

MySQL中的SQL常见调优策略测试

explain select * from test1 where c1 = '111'

MySQL中的SQL常见调优策略测试
我们可以看到没加where条件时,type是ALL(全表扫描),加了where的c1(索引)条件后type是ref,即哪些列或常量被用于查找索引列上的值。显然非全表扫描会快很多。

2.索引列排序

MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

explain select * from test1 where c1 = 'aaa' order by c3;

MySQL中的SQL常见调优策略测试

explain select * from test1 order by c1;

MySQL中的SQL常见调优策略测试
我们看到order by即使是用到了c1索引,type依然为ALL全表扫描。

3.like语句操作

一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引,而like “aaa%”可以使用索引。测试如下:

explain select * from test1 where c1 like '%a%';

MySQL中的SQL常见调优策略测试

explain select * from test1 where c1 like 'a%';

MySQL中的SQL常见调优策略测试

4.不要在列上进行运算或者对字段进行函数操作

例如:select * from users where YEAR(adddate)<2007,将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:select * from users where adddate<’2007-01-01′

explain select * from test1 where id/2 = 2;

MySQL中的SQL常见调优策略测试

explain select * from test1 where id = 2*2;

MySQL中的SQL常见调优策略测试

5.MySQL只对以下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些时候的like(不以通配符%或_开头的情形)。而理论上每张表里面最多可创建16个索引,不过除非是数据量真的很多,否则过多的使用索引也不是那么好玩的。

建议:一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

explain select * from test1 where c1 < 'a';

explain select * from test1 where c1 != 'aaa';

explain select * from test1 where c1 in ('aaa', 'aaa2');

explain select * from test1 where c1 not in ('aaa', 'aaa2');

MySQL中的SQL常见调优策略测试
MySQL中的SQL常见调优策略测试
MySQL中的SQL常见调优策略测试
MySQL中的SQL常见调优策略测试

6.避免使用or逻辑

应尽量避免在 where 子句中使用 or 来连接条件,迫不得已尽量写成IN:OR的效率是n级别,IN的效率是log(n)级别(in的个数建议控制在200以内),且用or链接条件将导致引擎放弃使用索引而进行全表扫描,如:

explain select * from test1 where c1 = 'aaa' or c2 = 'bbb';

MySQL中的SQL常见调优策略测试

explain

select * from test1 where c1 = 'aaa'

union all

select * from test1 where c2 = 'bbb';

MySQL中的SQL常见调优策略测试

7.慎用in和not in逻辑

in 和 not in 也要慎用,否则会导致全表扫描,如:

select id from t1 where num in(select id from t2 where id > 10)

此时外层查询会全表扫描,不使用索引。可以修改为:

select id from t1,(select id from t1 where id > 10)t2 where t1.id = t2.id

此时索引被使用,可以明显提升查询效率。

explain select * from test1 where c1 in (select c1 from test1);

MySQL中的SQL常见调优策略测试

explain select t1.c1,t1.c2 from test1 t1, (select c1 from test1) t where t1.c1 = t.c1;

MySQL中的SQL常见调优策略测试

8.如果列值单一,索引也可能失效

并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

9.表格字段类型选择

尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

尽可能的使用 varchar 代替 char ,因为首先可变长度字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

账号名建议用varchar,密码建议用char,varchar是可变字符的,char是固定长度的,密码通过加密后都是等长的字符。

10.查询语法中的字段

任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

上一篇:Mysql执行计划(大章)


下一篇:用 Explain 命令分析 MySQL 的 SQL 执行