小白学习MySQL - 一次慢SQL的定位
Posted bisal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小白学习MySQL - 一次慢SQL的定位相关的知识,希望对你有一定的参考价值。
同事提了个问题,某套测试环境mysql执行语句出现hang。
作为小白,每次碰到问题,都是在积累经验。执行SQL出现hang,说明应该有会话处于等待状态,可以通过show processlist看下当前的一些会话信息。
show processlist的敏感信息太多了,不截图了,现象是很多waiting for table level lock select ...、query end update ...。
首先看下系统负载的情况,top显示资源还是比较繁忙的,
磁盘读写不低,
再看下磁盘空间,/var路径已经满了,
经过沟通,MySQL的binlog放到了/var下,磁盘空间满了,不能写日志了,按照日志优先写的机制,不能操作数据库,这是正常现象。
从规范上,MySQL的binlog放到/var系统路径,并不是很合理,因为是测试环境,可能就很随意了,为了解决问题,先清理下路径。从截图来看,/var中有很多docker的镜像,了解了下,很多都是不用的镜像了,
删除无用的,释放出/var的空间,
docker rm 容器ID
docker rmi 镜像
此时数据库可以访问执行了,但是操作某张表,非常地慢,执行一条普通SQL,例如select * from test where cid='1';,cid存在索引,数据量是8千万,cid是int类型,执行计划如下,没有隐式转换,
按说应该毫秒出,但是都需要几秒,而且奇怪的是,即使执行explain,都需要几秒。这种情况,不应该只是这条语句的问题。
show processlist还是显示很多waiting for table level lock select ...,关于行锁的定位,可以参考《InnoDB快速定位行锁争用会话的过程和操作》,但这里提示的是表锁,而且是select等待表锁,再看下这张表的创建语句,他是按照ENGINE=MyISAM创建的,这就能解释了。
MyISAM引擎的锁粒度,是Table,读锁和写锁,是互斥的,就是说读写操作是串行的,而且默认写的优先级高于读,看资料说,存在一些参数,可以调整优先级,这需要综合考量,无论怎样调整,总有一种操作,优先级降低,他对应的逻辑,就会有影响,可能更加复杂,因此MyISAM引擎,按照官方推荐,适合于查询频繁的场景,如果对数据的增删改频率很高,还是推荐使用InnoDB,他的锁粒度是Row,
https://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html
经过沟通,当前的时间段,有个落数的程序,一直在跑之前几天丢的数据,就是说当前有频繁的更新操作,语句简单,就是update test set ... where cid=...,但就像上面所说,MyISAM引擎用的表锁,而且默认写,优先级高于读,select只能在很多update穿插中执行,抢到了资源,才可以执行。
待落数的程序,执行完成,此时select就快了,因为无资源争用,都给读了。咨询了下,之所以定义为MyISAM,是认为他会让SQL执行更快,的确,MyISAM不支持事务,不会像InnoDB为了保证事务一致性,需要做些操作,而且MyISAM的数据定位和缓存上,和InnoDB有所区别,一定程度上,对检索效率,可能有所提升。但是究竟用什么样的引擎,不应该只看效率,还需要结合实际的场景,综合考量。如果在检索同时,存在高并发的增删改操作,就会像上面这种,影响select效率,原本要通过MyISAM获得更高响应时间就成为了空谈。
因此,任何技术的选型,都需要在充分了解技术原理的前提下,结合实际场景,综合考量,权衡利弊,我们追求的应该不是最佳的,应该是最合适的。
小白学习MySQL,
《小白学习MySQL - TIMESTAMP类型字段非空和默认值属性的影响》
《小白学习MySQL - InnoDB支持optimize table?》
《小白学习MySQL - table_open_cache的作用》
《小白学习MySQL - only_full_group_by的校验规则》
《小白学习MySQL - max_allowed_packet》
《小白学习MySQL - mysqldump保证数据一致性的参数差异》
《小白学习MySQL - MySQL会不会受到“高水位”的影响?》
近期更新的文章:
文章分类和索引:
以上是关于小白学习MySQL - 一次慢SQL的定位的主要内容,如果未能解决你的问题,请参考以下文章