1.避免SELECT *
SELECT中每少提取一个字段,数据的提取速度就会有相应的提升。提升的速度还要看舍弃的字段的大小来判断。
2.建立索引
根据自己的需求适当建立索引,单个索引或联合索引。mysql建立联合索引的时候需要注意:有一个最左原则。
3.避免在列上运算,这样会导致索引失效
SELECT usercode,username,age FROM t WHERE score/10 = 9;
优化为
SELECT usercode,username,age FROM t WHERE score = 9*10;
4.使用 JOIN 时
应该用小结果集驱动大结果集,同时把复杂的 JOIN 查询拆分成多个query,因为 JOIN 多个表,可能导致更多的锁定和堵塞。可以用join代替复杂的子查询。
5.使用 LIKE 时
避免使用全模糊即'%%'查询,这样会进行全表扫描,不走索引。
SELECT usercode,username,age,score FROM t WHERE username LIKE '%王%';
优化为
SELECT usercode,username,age,score FROM t WHERE username LIKE '王%';
6.避免进行null值的判断
null值判断不走索引
SELECT usercode,username,age FROM t WHERE score IS NULL;
优化方式:可以给字段添加默认值0,对0值进行判断。如下:
SELECT usercode,username,age FROM t WHERE score = 0;
7.避免使用or
or 会进行全表扫描
SELECT id,username,age,score FROM t WHERE id = 1 OR usercode = '001';
优化方式:可以用union代替or。如下:
SELECT id,username,age,score FROM t WHERE id = 1
UNION
SELECT id,username,age,score FROM t WHERE usercode = '001';
8.避免使用in 和not in
SELECT usercode,username,age,score FROM t WHERE id IN (2,3);
SELECT usercode,username,age,score FROM t WHERE username IN (SELECT username FROM t1);
优化方式:如果是连续数值,可以用between代替。如下:
SELECT usercode,username,age,score FROM t WHERE id BETWEEN 2 AND 3;
如果是子查询,可以用exists代替。如下:
SELECT usercode,username,age,score FROM t WHERE EXISTS (SELECT * FROM t1 WHERE t.username = t1.username);
9.LIMIT
limit的基数比较大时,使用 between,between 限定比 limit 快,但是between也有缺陷,如果id中间有断行或是中间部分id不读取的情况,数据会少
select usercode,username,age,score from t where score=100 limit 100000,10;
优化为
select usercode,username,age,score from t where score=100 between 100000 and 100010;
10.慢sql调优
找到慢sql慢的原因,是什么引起慢的。可能是查询条件没有索引,或者查询出来的数据量太大。
1.查询条件没有索引
根据查询条件选择最好的索引字段建立索引。即这个字段的值比较分散相对不集中,且这个字段不能有null值,因为字段值集中枚举较少可能数据库引擎不会走索引;索引字段null 值,就不会走索引,会全表扫描。
2.数据量太大
如果是查询出来的数据量太大。导致某一个条件的值查询出来的数据量很多,占了整张表数据量的很大一部分。这就需要对数据进行分析,看看能不能通过查询的必选条件建立索引去除很大一部分数据,或者通过某几个条件可以去除大量数据,然后对这几个条件建立联合索引。