1.避免SELECT *

SELECT中每少提取一个字段,数据的提取速度就会有相应的提升。提升的速度还要看舍弃的字段大小来判断。

2.建立索引

根据自己的需求适当建立索引,单个索引或者联合索引。mysql建立联合索引时注意最左匹配原则。

3.避免在列上运算,这样会导致索引失效

1
SELECT name, score FROM t WHERE score/10 = 9;

改为

1
SELECT name, score FROM t WHERE score = 10 * 9;

4.使用JOIN时

应该用小结果集驱动大结果集,同时把复杂的JOIN查询拆分为多个查询,因为JOIN多个表可能导致更多的锁和堵塞。可以用JOIN代替复杂的字查询。

5.使用LIKE时

避免使用全模糊查询’%%’,因最左匹配这样不会走索引,会全表扫描。

1
SELECT name, score FROM t WHERE name LIKE '%王%';

改为

1
SELECT name, score FROM t WHERE name LIKE '王%';

6. 避免使用null值的判断

null不走索引。 可以给字段一个默认值,比如0。

1
SELECT name, score FROM t WHERE score IS NULL;

改为

1
SELECT name, score FROM t WHERE score = 0;

7. 避免使用or

or会走全表扫描

1
SELECT name, score FROM t WHERE score = 30 OR score = 40;

改为

1
2
3
SELECT name, score FROM t WHERE score = 30
UNION
SELECT name, score FROM t WHERE score = 40;

8.避免使用in和not in

1
2
SELECT name, score FROM t WHERE score IN (2,3);
SELECT name, score FROM t WHERE score IN (SELECT score FROM t1);

优化方式:如果是连续的值,可以用between代替。如下:

1
SELECT name, score FROM t WHERE score BETWEEN 2 AND 3;

如果是子查询,可以用exists代替。如下:

1
SELECT name, score FROM t WHERE EXISTS (SELECT * FROM t1 WHERE t.name = t1.name);

9.LIMIT

limit基数比较大时,使用between,between限定比limit快,但是between也有缺陷,如果id中间有断行或者是中间有部分id不读取的情况,数据会少

1
SELECT name, score FROM t WHERE socre = 100 limit 100000, 10;

改为

1
SELECT name, score FROM t WHERE socre = 100 BETWEEN 100000 and 100010;

10.慢sql调优

找到慢sql的原因,是什么引起慢的。可能是查询条件没有索引,或者查询出来的数据量太大。

  1. 查询条件没有索引
    根据查询条件选择最好的索引字段建立索引。即这个字段的值比较分散相对不集中,且这个字段不能有null值,因为字段值集中枚举较少可能数据库引擎不会走索引;索引字段null值,就不会走索引,会全表扫描。
    
  2. 数据量太大
    如果是查询出来的数据量太大。导致某一个条件的值查询出来的数据量很多,占了整张表数据量的很大一部分。这就需要对数据进行分析,看看能不能通过查询的必选条件建立索引去除很大一部分数据,或者通过某几个条件可以去除大量数据,然后对这几个条件建立联合索引。
    

评论




博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

载入天数...载入时分秒... 本站使用 Volantis 作为主题 鲁ICP备-20012065号