MySQL
MySQL高可用配置
MySQL Slave状态参数详解
基于二进制日志文件的复制
使用全局事务标识符GTID复制
MySQL安装升级
MySQL RPM包安装参考
MySQL编译化安装参考
MySQL Server版本升级
MySQL 操作手册/说明
MySQL导入导出操作
库,表,字段的字符集修改方法
根据字段生成自定义SQL语句
MySQL查询流程概述
MySQL 常用脚本
MySQL数据库冷备脚本
MySQL内存占用分析
MySQL内存消耗分析
检查MySQL引起的高内存占用
InnoDB下的内存分析和优化计算
MySQL常见问题
MySQL告警:Aborted connection日志的分析
MySQL使用命令kill进程后出现killed死锁问题
从库重起初始化relaylog失败
安全插件Connection-Control导致无法登录的问题
MySQL性能优化
MySQL查询慢性能分析
本文档使用 MrDoc 发布
-
+
home page
MySQL查询慢性能分析
# 可能的原因 ## 1. 未使用索引 查看是否建立了索引 ```sql mysql> show create table APP_TASK ; PRIMARY KEY (`ID`), KEY `idx_task_type` (`TASK_TYPE`), -- 表示有该字段的查询索引 ``` 如果未使用索引,则考虑是否需要建立索引加速 ## 2. 索引不符合预期 使用`explain` + `查询语句` 打印查询语句的情况分析: ```SQL -- 示例 mysql> explain select count(E.Status) from APP_TASK E WHERE E.TASK_TYPE = '6'; ``` ![](/media/202307/2023-07-28_151025_2297810.5394318566840691.png) 上面的语句中: - `type`的值的定义如下: all:代表全表扫描 ref:代表使用非唯一性索引或者唯一索引的前缀扫描 index:代表全索引扫描 range:索引范围扫描 eq_ref:类似ref, 使用索引是唯一索引 null:直接返回结果,无需访问表和索引 - `possible_keys`是指可能用得到的索引,这里可能使用到的索引是为idx_task_type建的普通索引 - `key`是指实际使用的索引,值为NULL表示不走索引,全表扫描。 - `rows` 预估这个查询语句需要查的行数的,不一定完全准确 ## 3. 连接数较少 正常情况下,客户端与server层如果只有一条连接,在执行sql查询之后,只能阻塞等待结果返回,如果有大量查询同时并发请求,后面的请求都需要等待前面的请求执行完成后,才能开始执行。 ![](/media/202307/2023-07-28_153016_5420600.17675770110547862.png) 查询方法: ```SQL mysql> show variables like 'max_connections'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 1500 | +-----------------+-------+ 1 row in set (0.06 sec) ``` 设置方法: ```SQL mysql> set global max_connections= 1500; Query OK, 0 rows affected (0.00 sec) ``` 4. 缓冲命中率过小 数据库查询流程中,在sql进入innodb后,会有一层内存buffer pool,用于将磁盘数据页加载到内存页中,如果查询到buffer pool中存在结果,就可以直接返回,否则需访问磁盘IO,降低查询速度。 理论上,buffer pool 越大,能放的数据页就越多,相应的,sql查询时就更可能命中buffer pool,查询速度更快。 可通过命令查询buffer pool的大小,单位是Byte。 查询buffer pool大小 ```sql mysql> show global variables like 'innodb_buffer_pool_size'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | innodb_buffer_pool_size | 67108864 | +-------------------------+----------+ 1 row in set (0.01 sec) ``` 设置buffer pool大小 ```SQL mysql> set global innodb_buffer_pool_size = 536870912; Query OK, 0 rows affected (0.01 sec) ``` 查看缓存命中率 ```SQL mysql> show status like 'Innodb_buffer_pool_%'; +---------------------------------------+--------------------------------------------------+ | Variable_name | Value | +---------------------------------------+--------------------------------------------------+ | Innodb_buffer_pool_dump_status | Dumping of buffer pool not started | | Innodb_buffer_pool_load_status | Buffer pool(s) load completed at 230317 11:01:06 | | Innodb_buffer_pool_resize_status | | | Innodb_buffer_pool_pages_data | 3063 | | Innodb_buffer_pool_bytes_data | 50184192 | | Innodb_buffer_pool_pages_dirty | 317 | | Innodb_buffer_pool_bytes_dirty | 5193728 | | Innodb_buffer_pool_pages_flushed | 82738697 | | Innodb_buffer_pool_pages_free | 1024 | | Innodb_buffer_pool_pages_misc | 8 | | Innodb_buffer_pool_pages_total | 4095 | | Innodb_buffer_pool_read_ahead_rnd | 0 | | Innodb_buffer_pool_read_ahead | 2187894 | | Innodb_buffer_pool_read_ahead_evicted | 6219 | | Innodb_buffer_pool_read_requests | 627326821 | | Innodb_buffer_pool_reads | 915095 | | Innodb_buffer_pool_wait_free | 10116 | | Innodb_buffer_pool_write_requests | 171976386 | +---------------------------------------+--------------------------------------------------+ 18 rows in set (0.01 sec) ``` 通过 show status like 'Innodb_buffer_pool_%';可以看到跟buffer pool有关的一些信息。 Innodb_buffer_pool_read_requests表示读请求的次数。 Innodb_buffer_pool_reads 表示从物理磁盘中读取数据的请求次数。 所以buffer pool的命中率就可以这样得到: 复制 buffer pool 命中率 = 1 - (Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests) * 100% 1. 比如我上面截图里的就是,1 - (405/2278354) = 99.98%。可以说命中率非常高了。 一般情况下buffer pool命中率都在99%以上,如果低于这个值,才需要考虑加大innodb buffer pool的大小。
Nathan
July 28, 2023, 3:46 p.m.
转发文档
Collection documents
Last
Next
手机扫码
Copy link
手机扫一扫转发分享
Copy link
Markdown文件
PDF文件
Docx文件
share
link
type
password
Update password