mysql性能优化是一个很大的命题,这里只记录一下近期的一些小经验。
曾经以为看了点create table时加index的语法就觉得自己知道怎么做mysql优化了,后来又看了点介绍mysql索引底层实现的文章,就感觉自己已经得到mysql精髓了一样。。
直到最近因为工作需要认真去提升大数据量下的性能的时候,才发现,自己以前简直跟从三到万里学了一二三就嚷嚷“儿得已”的三岁小儿一样的可笑。。
一、这里简单引用些资料介绍一些优化工具
神器1 https://dev.mysql.com/doc/refman/5.6/en/
官方文档手册,不需要解释。
神器2 explain
用这个看看自己的sql,经历哪些步骤,有没有使用到索引,不要想当然觉得建个索引mysql就能智能的到处使用,它有它的规则的,数据量大时有没有用到索引往往性能是天壤之别。参考资料:https://www.cnblogs.com/butterfly100/archive/2018/01/15/8287569.html
神器3 show engine innodb statusG
尤其推荐执行耗时很长的sql时看看最底下那里,mysql实际速度到底多少,它在忙哪类操作还是在发呆。。
另外可以看看buffer pool用的怎么样
神器4 show global status;
具体解释可以看这里 https://dev.mysql.com/doc/refman/5.6/en/server-status-variables.html
神器5 了解mysql buffer pool
参考这里:https://www.cnblogs.com/coderyuhui/p/6861194.html
官方文档:https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-pool.html
神器6 show full proccesslist;
查看当前正在执行的sql,也可以kill xxxx去杀掉query
二、最近使用的优化
实际操作中如何优化一定是结合业务场景来做的。例如少量写大量读的,可以用mysql一主多从、合理建索引、前面加一层redis等解决。这里只简单记录一点点
1. 合理使用索引
(1)建议使用组合索引,从explain可以看到一次子查询mysql只会选一个index使用,所以每个字段建一个索引最后也只会使用到其中一个而不是挨个去用。
(2)索引的字段不能太长,组合所有字段加起来长度在768字节以内才行,否则mysql自动取字段前xx字节
(3)把自己的sql用explain看看,确认一下mysql是怎么理解和执行的,是不是符合预期
(4)索引太多不见得好,会影响增删改的性能,以及造成数据膨胀,占用更多的磁盘空间。
2. 合理使用分区表
分区表的使用限制很多,多数情况下不推荐使用,但是刚好完全符合它的特性的时候建议果断用。用好了比自己分表要简单省事的多。
使用原则:
(1)所有查询都要指定分区字段,否则mysql就扫全表并且忽略所有索引
(2)合理的分区个数,底层是每个分区一套文件的,太多太少都不合适。当然自己分表也是一样要确定合理的分表个数。
(3)尽量应用在不需要alter table的场景里,alter table时如果分区较多,性能比普通表要慢很多。
3. 大数据量并且查询多的情况,尽量避免大数据量的join,可以加工制作宽表的方式进行优化。宽表上还可以建索引等。
4. 大批量关联update时,如果无法使用到索引,可以考虑是否方便先insert into select 然后delete老数据。当然这个办法更trick,一般场景是不建议使用的。不过trick的办法都是因地制宜想出来的,了解mysql特性并结合业务场景灵活运用就是好的设计。