mysql语句优化原则

有时候发现数据量大的时候查询起来效率就比较慢了,学习一下mysql语句优化的原则,自己在正常写sql的时候还没注意到这些,先记录下来,慢慢一点一点的学,加油!

这几篇博客写的都可以:

https://blog.csdn.net/s1547823103/article/details/79205670

https://blog.csdn.net/u011277123/article/details/78904569

 

使用索引的原则:

1.最左前缀匹配原则。

mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。所以要尽量把“=”条件放在前面,这些条件放在最后。

不会用到b的索引:

where a=1 and c>0 and b=2

会用到b的索引:

where a=1 and b=2 and c>0

 

2.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少。

 

3.当取出的数据超过全表数据的20%时,不会使用索引。

 

4.使用like时注意:

不使用索引:

like ‘%L%’

使用索引:

like ‘L%’

 

5.尽量将or 转换为 union all

不使用索引:

select * from user where name=’a’ or age=’20’

使用索引:

select * from user where name=’a’ union all select * from user where age=’20’

 

6.字段加函数不会使用索引。所以尽量把函数放在数值上

不使用索引:

where truncate(price) = 1

使用索引:

where price > 1 and price < 2

 

 

7.如果使用数字作为字符,则数字需要加引号,否则mysql会自动在列上加数据类型转换函数

 

不使用索引

 

where mobile=18534874321

 

使用索引

 

where mobile=’18534874321’

 

 

8.字段加运算符不会使用索引。所以尽量把运算放在数值上

 

不使用索引:

 

SELECT ACCOUNT_NAME, AMOUNT FROM TRANSACTION WHERE AMOUNT + 3000 >5000;

 

使用索引:

 

SELECT ACCOUNT_NAME, AMOUNT FROM TRANSACTION WHERE AMOUNT > 2000 ;

 

 

9.使用组合索引时,必须要包括第一个列。

 

例如

 

alter table test add index(a,b,c):

 

不使用索引:

 

where b=1, c=2

 

where b=1

 

where c=2

 

使用索引:

 

where a=1, b=1, c=2

 

where a=1, b=1

 

where a=1, c=2

 

 

10.尽量避免使用is null或is not null

 

不使用索引:

 

SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;

 

使用索引:

 

SELECT … FROM DEPARTMENT WHERE DEPT_CODE >0;

 

 

11.不等于(!=)不会使用索引

 

不使用索引:

 

SELECT ACCOUNT_NAME FROM TRANSACTION WHERE AMOUNT !=0;

 

使用索引:

 

SELECT ACCOUNT_NAME FROM TRANSACTION WHERE AMOUNT >0;

 

 

12.ORDER BY 子句只在以下的条件下使用索引:

 

ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.

 

ORDER BY中不能既有ASC也有DESC

 

例如:

 

alter table t1 add index(a,b);

 

alter table t1 add index(c);

 

不使用索引:

 

select * from t1 order by a,c; 不在一个索引中

 

select * from t1 order by b; 没有出现组合索引的第一列

 

select * from t1 order by a asc, b desc; 混合ASC和DESC

 

select * from t1 where a=1 order by c; where和order by用的不是同一个索引,where使用索引,order by不使用。

 

使用索引:

 

select * from t1 order by a,b;

 

select * from t1 order where a=1 order by b;

 

select * from t1 order where a=1 order by a,b;

 

select * from t1 order by a desc, b desc;

 

select * from t1 where c=1 order by c;

 

 

13.索引不是越多越好。mysql需要资源来维护索引,任何数据的变更(增删改)都会连带修改索引的值。所以,需要平衡考虑索引带来的查询加速和增删改减速。

 

其他注意事项

 

1.尽量避免使用select *

 

2.尽量使用表连接(join)代替子查询select * from t1 where a in (select b from t2)

 

3.性能方面,表连接 > (not) exists > (not) in

 

posted @ 2019-03-05 16:26  思丿无邪  阅读(217)  评论(0编辑  收藏  举报