如何使用 MySQL 慢查询日志进行性能优化 - Profiling、mysqldumpslow 实例详解

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当我们开始关注数据库整体性能优化时,我们需要一套 MySQL 查询分析工具。特别是在开发中大型项目时,往往有数百个查询分布在代码库中的各个角落,并实时对数据库进行大量访问和查询。如果没有一套趁手的分析方法和工具,就很难发现在执行过程中代码的效率瓶颈,我们需要通过这套工具去定位 SQL 语句在执行中缓慢的问题和原因。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本教程带领大家学习和实践 MySQL Server 内置的查询分析工具 —— 慢查询日志、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Profiling","attrs":{}}],"attrs":{}},{"type":"text","text":",详细讲解如何使用他们提升代码执行效率。如果你想根据自己的工作流开发一套数据库查询管理工具,推荐使用卡拉云。只要你会写 SQL,无需会前端也可以轻松搭建属于自己的后台查询工具,详见本文文末。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一. 有关 MySQL 慢查询日志","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1.慢查询日志是什么?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"MySQL 慢查询日志是用来记录 MySQL 在执行命令中,响应时间超过预设阈值的 SQL 语句。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"记录这些执行缓慢的 SQL 语句是优化 MySQL 数据库效率的第一步。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默认情况下,慢查询日志功能是关闭的,需要我们手动打开。当然,如果不是调优需求的话,一般也不建议长期启动这个功能,因为开启慢查询多少会对数据库的性能带来一些影响。慢查询日志支持将记录写入文件,当然也可以直接写入数据库的表中。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.配置并打开慢查询日志","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"(1)在 MySQL Server 中临时开启慢查询功能","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 MySQL Server 中,默认情况慢查询功能是关闭的,我们可以通过查看此功能的状态","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"show variables like 'slow_query_log'; ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/75/758308c7952bb537f2ce5245660cd809.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如上图所示,慢查询日志(slow_query_log )的状态为关闭。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以使用以下命令开启并配置慢查询日志功能,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"在 mysql 中执行以下命令","attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SET GLOBAL slow_query_log = 'ON';\nSET GLOBAL slow_query_log_file = '/var/log/mysql/kalacloud-slow.log';\nSET GLOBAL log_queries_not_using_indexes = 'ON';\nSET SESSION long_query_time = 1;\nSET SESSION min_examined_row_limit = 100;\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"SET GLOBAL slow_query_log","attrs":{}}],"attrs":{}},{"type":"text","text":" :全局开启慢查询功能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"SET GLOBAL slow_query_log_file","attrs":{}}],"attrs":{}},{"type":"text","text":" :指定慢查询日志存储文件的地址和文件名。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"SET GLOBAL log_queries_not_using_indexes","attrs":{}}],"attrs":{}},{"type":"text","text":":无论是否超时,未被索引的记录也会记录下来。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"SET SESSION long_query_time","attrs":{}}],"attrs":{}},{"type":"text","text":":慢查询阈值(秒),SQL 执行超过这个阈值将被记录在日志中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"SET SESSION min_examined_row_limit","attrs":{}}],"attrs":{}},{"type":"text","text":":慢查询仅记录扫描行数大于此参数的 SQL。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"**特别注意:**在实践中常常会碰到无论慢查询阈值调到多小,日志就是不被记录。这个问题很有可能是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"min_examined_row_limit","attrs":{}}],"attrs":{}},{"type":"text","text":" 行数过大,导致没有被记录。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"min_examined_row_limit","attrs":{}}],"attrs":{}},{"type":"text","text":" 在配置中常被忽略,这里要特别注意。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着我们来执行查询语句,看看配置。(在 MySQL Server 中执行)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"show variables like 'slow_query_log%';\nshow variables like 'log_queries_not_using_indexes';\nshow variables like 'long_query_time';\nshow variables like 'min_examined_row_limit';\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9e/9e92c9e3c33d2c3cd16c336fe050a7b4.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上修改 MySQL 慢查询配置的方法是用在","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"临时监测数据库运行状态","attrs":{}},{"type":"text","text":"的场景下,当 MySQL Server 重启时,以上修改全部失效并恢复原状。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"扩展阅读:","attrs":{}},{"type":"link","attrs":{"href":"https://kalacloud.com/blog/how-to-manage-and-use-mysql-database-triggers/","title":"","type":null},"content":[{"type":"text","text":"六类 MySQL 触发器使用教程及应用场景实战案例","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"(2)将慢查询设置写入 MySQL 配置文件,永久生效","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"虽然我们可以在命令行中对慢查询进行动态设置,但动态设置会随着重启服务而失效。如果想长期开启慢查询功能,需要把慢查询的设置写入 MySQL 配置文件中,这样无论是重启服务器,还是重启 MySQL ,慢查询的设置都会保持不变。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"MySQL conf 配置文件通常在 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"/etc","attrs":{}}],"attrs":{}},{"type":"text","text":" 或 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"/usr","attrs":{}}],"attrs":{}},{"type":"text","text":" 中。我们可以使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"find","attrs":{}}],"attrs":{}},{"type":"text","text":" 命令找到配置文件具体的存放位置。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"sudo find /etc -name my.cnf\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d6/d6e6585002430ca97819bc9f9105bd65.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"找到位置后,使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"nano","attrs":{}}],"attrs":{}},{"type":"text","text":" 编辑 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"my.cnf","attrs":{}}],"attrs":{}},{"type":"text","text":" 将慢查询设置写入配置文件。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"sudo nano /etc/mysql/my.cnf\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"[mysqld]\n\nslow-query-log = 1\nslow-query-log-file = /var/log/mysql/localhost-slow.log\nlong_query_time = 1\nlog-queries-not-using-indexes\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"nano","attrs":{}}],"attrs":{}},{"type":"text","text":" 打开配置文件,把上面的的代码写在 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"[mysqld]","attrs":{}}],"attrs":{}},{"type":"text","text":" 的下面即可。 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ctrl+X","attrs":{}}],"attrs":{}},{"type":"text","text":" 保存退出。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"sudo systemctl restart mysql\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重启 MySQL Server 服务,使刚刚修改的配置文件生效。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"**特别注意:**直接在命令行中设置的慢查询动态变量与直接写入 my.cnf 配置文件的语法有所不同。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"扩展阅读:10种 ","attrs":{}},{"type":"link","attrs":{"href":"https://kalacloud.com/blog/best-mysql-gui-tools/","title":"","type":null},"content":[{"type":"text","text":"MySQL 管理工具","attrs":{}}]},{"type":"text","text":" 横向测评 - 免费和付费到底怎么选?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"举例:动态变量是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"slow_query_log","attrs":{}}],"attrs":{}},{"type":"text","text":",写入配置文件是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"slow-query-log","attrs":{}}],"attrs":{}},{"type":"text","text":"。这里要特别注意。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"更多 MySQL 8.0 动态变量语法可查看 ","attrs":{}},{"type":"link","attrs":{"href":"https://dev.mysql.com/doc/refman/8.0/en/dynamic-system-variables.html","title":"","type":null},"content":[{"type":"text","text":"MySQL 官方文档","attrs":{}}]},{"type":"text","text":"。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二. 使用慢查询功能记录日志","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"到这里我们已经配置好慢查询功能所需要的一切。下面咱们写一个示例,在这个示例中我们来一起学习如何查看和分析慢查询日志。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你可以打开两个连接到服务器的命令行窗口,一个用来写 MySQL 代码,另一个用来查看日志。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"注意:以下教程中,有些代码是在命令行中执行,有些是在 MySQL Server 中执行,请注意分辨。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"登录 MySQL Server,创建一个数据库,写入一组示例数据。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"CREATE DATABASE kalacloud_demo;\nUSE kalacloud_demo;\nCREATE TABLE users ( id TINYINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) );\nINSERT INTO users (name) VALUES ('Jack Ma'),('Lei Jun'),('Wang Xing'),('Pony Ma'),('Zhang YiMing'),('Ding Lei'),('Robin Li'),('Xu Yong'),('Huang Zheng'),('Richard Liu');\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了保证大家与教程配置保持一致,咱们一起使用动态变量,再设置一边慢查询参数。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 MySQL Server 中执行以下 SQL 代码:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SET GLOBAL slow_query_log = 1;\nSET GLOBAL slow_query_log_file = '/var/log/mysql/kalacloud-slow.log';\nSET GLOBAL log_queries_not_using_indexes = 1;\nSET long_query_time = 10;\nSET min_examined_row_limit = 0;\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在我们有了一个表中有数据的示例数据库。慢查询功能也已经打开,我们特意把时间阈值(long_query_time)设置为 10 并且把最小行(min_examined_row_limit)设置为 0。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着我们来运行一段代码测试一下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"USE kalacloud_demo;\nSELECT * FROM users WHERE id = 1;\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用主键索引对表进行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"select","attrs":{}}],"attrs":{}},{"type":"text","text":" 查询,这种查询速度非常快,又使用了索引。因此慢查询日志中不会有任何记录。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们打开慢查询日志,验证一下是否有记录,在命令行中执行以下命令:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"sudo cat /var/log/mysql/kalacloud-slow.log\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"kalacloud-slow.log","attrs":{}}],"attrs":{}},{"type":"text","text":"还没有任何记录。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b9/b9313cd2c306ce3a1797c8a3ff21a7be.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着我们在 MySQL Server 中执行以下代码:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SELECT * FROM users WHERE name = 'Wang Xing';\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这段查询代码使用非索引列(name)来进行查询,所以慢查询日志在会记录下这个查询。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们打开日志查看记录变化:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"sudo cat /var/log/mysql/kalacloud-slow.log\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ef/ef6ea84e57b67d7026f5d146a2b4d26a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以看到这个非索引查询,已经被记录在慢查询日志中了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再举个例子。我们提高最小检查行(min_examined_row_limit)的检查行数设置为 100,然后再执行查询。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 MySQL Server 中执行以下代码:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SET min_examined_row_limit = 100;\nSELECT * FROM users WHERE name = 'Zhang YiMing';\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"执行后,再打开 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"kalacloud-slow.log","attrs":{}}],"attrs":{}},{"type":"text","text":" ,可以看到条小于 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"100","attrs":{}}],"attrs":{}},{"type":"text","text":" 行的查询,没有被记录到日志中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"特别注意","attrs":{}},{"type":"text","text":":如果慢查询日志中,没有记录任何数据,可以检查以下内容。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(1)创建日志的目录权限问题,是否有对应的权限。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"cd /var/log\nmkdir mysql\nchmod 755 mysql\nchown mysql:mysql mysql\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(2)另一个可能是查询变量配置问题,把 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"my.conf","attrs":{}}],"attrs":{}},{"type":"text","text":" 文件内有关慢查询的配置清干净,然后重启服务,重新配置。看看是不是这里出的问题。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"扩展阅读:","attrs":{}},{"type":"link","attrs":{"href":"https://kalacloud.com/blog/how-to-save-mysql-mariadb-query-output-to-a-file/","title":"","type":null},"content":[{"type":"text","text":"如何将 MySQL 的查询结果保存到文件","attrs":{}}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三. 慢查询日志记录参数详解","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着我们来讲解慢查询日志应该如何分析","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ef/ef6ea84e57b67d7026f5d146a2b4d26a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"日志中信息的说明:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Time","attrs":{}}],"attrs":{}},{"type":"text","text":" :被日志记录的代码在服务器上的运行时间。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"User@Host","attrs":{}}],"attrs":{}},{"type":"text","text":":谁执行的这段代码。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Query_time","attrs":{}}],"attrs":{}},{"type":"text","text":":这段代码运行时长。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Lock_time","attrs":{}}],"attrs":{}},{"type":"text","text":":执行这段代码时,锁定了多久。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Rows_sent","attrs":{}}],"attrs":{}},{"type":"text","text":":慢查询返回的记录。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Rows_examined","attrs":{}}],"attrs":{}},{"type":"text","text":":慢查询扫描过的行数。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这些被记录的信息非常有意义,所有超过阈值的代码都会被记录在日志中,我们可以通过这些信息找到 MySQL 查询时效率不佳的代码,有助于我们优化 MySQL 性能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"扩展阅读:","attrs":{}},{"type":"link","attrs":{"href":"https://kalacloud.com/blog/find-all-tables-with-specific-column-names-in-mysql/","title":"","type":null},"content":[{"type":"text","text":"如何在 MySQL 里查询数据库中带有某个字段的所有表名","attrs":{}}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"四. 使用 mysqldumpslow 工具对慢查询日志进行分析","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"实际工作中,慢查询日志可不像上文描述的那样,仅仅有几行记录。现实中慢查询日志会记录大量慢查询信息,写入也非常频繁。日志记录的内容会越来越长,分析数据也变的困难。 好在 MySQL 内置了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 工具,它可以把相同的 SQL 归为一类,并统计出归类项的执行次数和每次执行的耗时等一系列对应的情况。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们先来执行几行代码让慢查询日志记录下来,然后再用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 进行分析。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上文我们把","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"min_examined_row_limit","attrs":{}}],"attrs":{}},{"type":"text","text":" 设置为 100,在这里,我们要将它改为 0 ,慢查询才能有记录。在 MySQL Server 中执行以下代码:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SET min_examined_row_limit = 0;\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着我们执行几条查询命令:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SELECT * FROM users WHERE name = 'Wang Xing';\nSELECT * FROM users WHERE name = 'Huang Zheng';\nSELECT * FROM users WHERE name = 'Zhang YiMing';\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根据前文的慢查询设置,这三条记录都将被记录在日志中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"我们切换到命令行的窗口中","attrs":{}},{"type":"text","text":",执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 命令:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"sudo mysqldumpslow -s at /var/log/mysql/kalacloud-slow.log\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"返回的数据:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e6/e66c8d435201f58a4d01999508321e35.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以看到,返回的数据中,已经把三条类似的 SQL 语句记录抽象成一条记录","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SELECT * FROM users WHERE name = 'S'","attrs":{}}],"attrs":{}},{"type":"text","text":" 并且针对这条记录列出了对应的总量和平均量的记录。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"常见的","attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"命令","attrs":{}},{"type":"text","text":" 平时大家也可以根据自己的常用需求来总结,存好这些脚本备用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow -s at -t 10 kalacloud-slow.log","attrs":{}}],"attrs":{}},{"type":"text","text":":平均执行时长最长的前 10 条 SQL 代码。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow -s al -t 10 kalacloud-slow.log","attrs":{}}],"attrs":{}},{"type":"text","text":":平均锁定时间最长的前10条 SQL 代码。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow -s c -t 10 kalacloud-slow.log","attrs":{}}],"attrs":{}},{"type":"text","text":":执行次数最多的前10条 SQL 代码。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow -a -g 'user' kalacloud-slow.log","attrs":{}}],"attrs":{}},{"type":"text","text":":显示所有 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"user","attrs":{}}],"attrs":{}},{"type":"text","text":" 表相关的 SQL 代码的具体值","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow -a kalacloud-slow.log","attrs":{}}],"attrs":{}},{"type":"text","text":":直接显示 SQL 代码的情况。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 的参数命令","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]\n\nParse and summarize the MySQL slow query log. Options are\n\n --verbose verbose\n --debug debug\n --help write this text to standard output\n -v verbose\n -d debug\n -s ORDER what to sort by (al, at, ar, c, l, r, t), 'at' is default\n al: average lock time\n ar: average rows sent\n at: average query time\n c: count\n l: lock time\n r: rows sent\n t: query time\n -r reverse the sort order (largest last instead of first)\n -t NUM just show the top n queries\n -a don't abstract all numbers to N and strings to 'S'\n -n NUM abstract numbers with at least n digits within names\n -g PATTERN grep: only consider stmts that include this string\n -h HOSTNAME hostname of db server for *-slow.log filename (can be wildcard),\n default is '*', i.e. match all\n -i NAME name of server instance (if using mysql.server startup script)\n -l don't subtract lock time from total time\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"常用的参数讲解:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"-s","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"al:平均锁定时间","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"at:平均查询时间 [默认]","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ar:平均返回记录时间","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"c:count 总执行次数","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"l:锁定时间","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"r:返回记录","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"t:查询时间","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"-t","attrs":{}}],"attrs":{}},{"type":"text","text":":返回前 N 条的数据","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"-g","attrs":{}}],"attrs":{}},{"type":"text","text":":可写正则表达,类似于 grep 命令,过滤出需要的信息。如,只查询 X 表的慢查询记录。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"-r","attrs":{}}],"attrs":{}},{"type":"text","text":":rows sent 总返回行数。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 日志查询工具好用就好用在它特别灵活,又可以合并同类项式的分析慢查询日志。我们在日常工作的使用中,就能够体会 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 的好用之处。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 的使用参数也可在 ","attrs":{}},{"type":"link","attrs":{"href":"https://dev.mysql.com/doc/refman/8.0/en/mysqldumpslow.html","title":"","type":null},"content":[{"type":"text","text":"MySQL 8.0 使用手册","attrs":{}}]},{"type":"text","text":" 中找到。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"扩展阅读:","attrs":{}},{"type":"link","attrs":{"href":"https://kalacloud.com/blog/how-to-get-the-sizes-of-the-tables-of-a-mysql-database/","title":"","type":null},"content":[{"type":"text","text":"如何查看 MySQL 数据库、表、索引容量大小","attrs":{}}]},{"type":"text","text":"?找到占用空间最大的表","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"五. Profilling - MySQL 性能分析工具","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了更精准的定位一条 SQL 语句的性能问题,我们需要拆分这条语句运行时到底在什么地方消耗了多少资源。 我们可以使用 Profilling 工具来进行这类细致的分析。我们可通过 Profilling 工具获取一条 SQL 语句在执行过程中对各种资源消耗的细节。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"进入 MySQL Server 后,执行以下代码,启动 Profilling","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SET SESSION profiling = 1; \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"检查 profiling 的状态","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SELECT @@profiling;\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"返回数据: 0 表示未开启,1 表示已开启。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ae/ae5abdc4e1ce094e75dc9d2b536c481a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"执行需要定位问题的 SQL 语句。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"USE kalacloud_demo;\nSELECT * FROM users WHERE name = 'Jack Ma';\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查看 SQL 语句状态。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SHOW PROFILES;\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"打开 profiling 后,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"SHOW PROFILES;","attrs":{}}],"attrs":{}},{"type":"text","text":" 会显示一个将 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Query_ID","attrs":{}}],"attrs":{}},{"type":"text","text":" 链接到 SQL 语句的表。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4f/4f771bdda2f733c660eb4a263a027840.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Query_ID","attrs":{}}],"attrs":{}},{"type":"text","text":":SQL 语句的 ID 编号。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Duration","attrs":{}}],"attrs":{}},{"type":"text","text":":SQL 语句执行时长。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Query","attrs":{}}],"attrs":{}},{"type":"text","text":":具体的 SQL 语句。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"执行以下 SQL 代码,将 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"[# Query_ID]","attrs":{}}],"attrs":{}},{"type":"text","text":" 替换为我们要分析的 SQL 代码","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Query_ID","attrs":{}}],"attrs":{}},{"type":"text","text":"的编号。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SHOW PROFILE CPU, BLOCK IO FOR QUERY [# Query_ID];\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"即","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SHOW PROFILE CPU, BLOCK IO FOR QUERY 4;\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b4/b4e3b259d7d04c581cb996210fa1c761.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Status","attrs":{}}],"attrs":{}},{"type":"text","text":" 是执行查询过程中的具体步骤,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Duration","attrs":{}}],"attrs":{}},{"type":"text","text":" 是完成该步骤所需的时间(以秒为单位)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以根据这些细节来具体分析,如何优化对应的 SQL 代码。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"六. 慢查询教程总结","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"慢查询是让我们看到数据库真实运行状态的工具,对服务器和数据库性能优化有着指导性的意义。无论是生产环境、开发、QA,都可以谨慎的打开慢查询来记录性能日志。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以先把动态变量","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"long_query_time","attrs":{}}],"attrs":{}},{"type":"text","text":" 设置的大一些,观察一下,然后在进行微调。有了慢查询日志,我们就有了优化性能的方向和目标,再使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mysqldumpslow","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"profiling","attrs":{}}],"attrs":{}},{"type":"text","text":" 进行宏观和微观的日志分析。找到低效 SQL 语句的细节,进行微调,最终使我们的系统可以获得最佳执行性能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"至此,MySQL 慢查询日志我们就讲解完了,如果你周期性的查看 log 日志,可以使用卡拉云搭一个日志看板,自己不仅查看、分析数据方便,还可以一键分享给组内的小伙伴共享数据。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"卡拉云是新一代低代码开发工具,免安装部署,可一键接入包括 MySQL 在内的常见数据库及 API。不仅可以像命令行一样灵活,还可根据自己的工作流,定制开发。无需繁琐的前端开发,只需要简单拖拽,即可快速搭建企业内部工具。","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"数月的开发工作量,使用卡拉云后可缩减至数天","attrs":{}},{"type":"text","text":",欢迎使用我开发的","attrs":{}},{"type":"link","attrs":{"href":"https://kalacloud.com/?utm_medium=register","title":"","type":null},"content":[{"type":"text","text":"卡拉云","attrs":{}}]},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8b/8bcdd52d6492ff4ada86801282362bbe.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"卡拉云可快速接入的常见数据库及 API","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"卡拉云可根据公司工作流需求,轻松搭建数据看板,并且可分享给组内的小伙伴共享数据","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/54/5400a60956e16d655e0297c5d6e5a8d2.gif","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"仅需拖拽一键生成前端代码,简单一行代码即可映射数据到指定组件中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ab/abab46cb6a2c70c2b3e2e944c5d4610e.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"卡拉云可直接添加导出按钮,导出适用于各类分析软件的数据格式,方便快捷。立即开通","attrs":{}},{"type":"link","attrs":{"href":"https://kalacloud.com/?utm_medium=register","title":"","type":null},"content":[{"type":"text","text":"卡拉云","attrs":{}}]},{"type":"text","text":",快速搭建属于你自己的后台管理系统。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有关 MySQL 教程,可继续拓展学习:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://kalacloud.com/blog/how-to-allow-remote-access-to-mysql/","title":"","type":null},"content":[{"type":"text","text":"如何远程连接 MySQL 数据库,阿里云腾讯云外网连接教程","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://kalacloud.com/blog/how-to-import-and-export-databases-excel-csv-in-mysql-or-mariadb-from-terminal/","title":"","type":null},"content":[{"type":"text","text":"如何在 MySQL / MariaDB 中导入导出数据,导入导出数据库文件、Excel、CSV","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://kalacloud.com/blog/how-to-migrate-a-mysql-database-between-two-servers-aliyun-tencentyun/","title":"","type":null},"content":[{"type":"text","text":"如何在两台服务器之间迁移 MySQL 数据库 阿里云腾讯云迁移案例","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://kalacloud.com/blog/how-to-use-the-mysql-blob-data-type-to-store-images-with-php-or-kalacloud/","title":"","type":null},"content":[{"type":"text","text":"MySQL 中如何实现 BLOB 数据类型的存取,BLOB 有哪些应用场景?","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://kalacloud.com/blog/mysql-workbench-tutorial/","title":"","type":null},"content":[{"type":"text","text":"如何使用 MySQL Workbench 操作 MySQL / MariaDB 数据库中文指南","attrs":{}}]}]}]}],"attrs":{}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章