Mysql-优化

查询优化

1、explain查询分析器,查看执行计划

2、索引的设计

3、慢查询日志,调试环境可以开启

4、查询缓存,区分业务,不经常变更的业务可以开启

show global status like 'QCache%';

show global status like 'Com_select';

查询缓存命中率 = Qcache_hits/(Qcache_hits + Com_select),

查询缓存命中率多大才是好的命中率,需要具体情况具体分析。

推荐一个指标:”命中和写入“的比率,即Qcache_hits和Qcache_inserts的比值。

根据经验来看,当这个比值大于3:1时通常查询缓存是有效的,如果能达到10:1最好

索引设计

1、在经常用作where条件和group/order by的字段上建立索引

2、最左前缀匹配原则

3、尽量选择区分度高的列作为索引

4、索引列不能参与运算,如date(update_time) 这样是用不到索引的

5、尽量扩展索引,不要新建索引

索引最左匹配原则

mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配

比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。即,组合索引的第一个字段必须出现在查询组句中,这个索引才会被用到。

解释:(a,b,c,d)的索引,索引匹配顺序a-b-c-d,而由于where c >3停止匹配,所以d就用不到索引了

           (a,b,d,c)的索引,索引匹配顺序a-b-d-c,为何可以用到d了呢,注意最左匹配说的是索引的匹配,并不是where条件的顺序

设计优化

1、数据库字段的设计,适度冗余字段,避免join

2、做分库分表

3、分库分表的ER表的设计,例如order-orderdetail,同一个订单号落在同一个库中

4、跨库join,通过建立全局表,冗余字段来避免

EXPLAIN

possible_keys:表示搜索可能用到的索引

key:表示实际选用的索引,如果没有选择索引,是NULL

有一种可能是possible_keys为空,但是key不为空的情况。

这种情况下说明mysql无法利用索引来搜索数据,但是返回的列却是某个索引的一部分,因此可以用覆盖索引的方式优化全表扫描。

https://ruby-china.org/topics/27022 末尾的评论

key_len:显示MySQL决定使用的键长度,如果键是NULL,则长度为NULL

如,字段a(int 4) b(int 3),查询时只用到复合索引(a,b)中的a,则key_len=4,实际使用的键的字节长度,若两个都用到了key_len=7

rows:显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。

ref:ref列显示哪些列或常量与键列中指定的索引进行比较,即显示索引的哪一列被使用了

type:连接类型

从最好到最差的连接类型为 const、eq_reg、ref、range、index和ALL

const:最多有一行匹配,如使用RIMARY KEY or UNIQUE index作为条件查询时

eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。除了system(只有一行)和const类型,这是最好的连接类型。

ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取

..

index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

ALL:对于每个来自于先前的表的行组合,进行完整的表扫描。

filtered:显示了通过条件过滤出的行数的百分比估计值

参考:

https://tech.meituan.com/mysql-index.html

https://www.zhihu.com/question/36996520

https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

http://blog.csdn.net/mccand1234/article/details/66475382

http://overtrue.me/articles/2014/10/mysql-explain.html

https://ruby-china.org/topics/27022

你可能感兴趣的:(Mysql-优化)