当前位置:网站首页>面试官:MySQL 数据库查询慢,除了索引问题还可能是什么原因?
面试官:MySQL 数据库查询慢,除了索引问题还可能是什么原因?
2022-07-23 14:43:00 【InfoQ】
数据库查询流程
CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '名字',
`age` int(11) NOT NULL DEFAULT '0' COMMENT '年龄',
`gender` int(8) NOT NULL DEFAULT '0' COMMENT '性别',
PRIMARY KEY (`id`),
KEY `idx_age` (`age`),
KEY `idx_gender` (`gender`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
select * from user where gender = 1 and age = 100;
lslectYou have an error in your SQL syntax;
CREATE TABLE `user` (
...
) ENGINE=InnoDB;


慢查询分析
profilingmysql> set profiling=ON;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show variables like 'profiling';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| profiling | ON |
+---------------+-------+
1 row in set (0.00 sec)
show profiles;mysql> show profiles;
+----------+------------+---------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+---------------------------------------------------+
| 1 | 0.06811025 | select * from user where age>=60 |
| 2 | 0.00151375 | select * from user where gender = 2 and age = 80 |
| 3 | 0.00230425 | select * from user where gender = 2 and age = 60 |
| 4 | 0.00070400 | select * from user where gender = 2 and age = 100 |
| 5 | 0.07797650 | select * from user where age!=60 |
+----------+------------+---------------------------------------------------+
5 rows in set, 1 warning (0.00 sec)
query_idselect * from user where age>=60mysql> show profile for query 1;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000074 |
| checking permissions | 0.000010 |
| Opening tables | 0.000034 |
| init | 0.000032 |
| System lock | 0.000027 |
| optimizing | 0.000020 |
| statistics | 0.000058 |
| preparing | 0.000018 |
| executing | 0.000013 |
| Sending data | 0.067701 |
| end | 0.000021 |
| query end | 0.000015 |
| closing tables | 0.000014 |
| freeing items | 0.000047 |
| cleaning up | 0.000027 |
+----------------------+----------+
15 rows in set, 1 warning (0.00 sec)
Sending data索引相关原因
- 选择这个索引大概要扫描多少行(rows)
- 为了把这些行取出来,需要读多少个16kb的页
- 走普通索引需要回表,主键索引则不需要,回表成本大不大?
explain select * from user where age>=60
typepossible_keyskeyNULLrows索引不符合预期
force index
explain走了索引还是很慢
explain
- 如果这个字段具有唯一的属性,比如电话号码等,一般是不应该有大量重复的,那可能是你代码逻辑出现了大量重复插入的操作,你需要检查下代码逻辑,或者需要加个唯一索引限制下。
- 如果这个字段下的数据就是会很大,是否需要全部拿?如果不需要,加个
limit限制下。如果确实要拿全部,那也不能一次性全拿,今天你数据量小,可能一次取一两万都没啥压力,万一哪天涨到了十万级别,那一次性取就有点吃不消了。你可能需要分批次取,具体操作是先用order by id排序一下,拿到一批数据后取最大id作为下次取数据的起始位置。
连接数过小


数据库连接数过小
10016384max_connectionsmysql> set global max_connections= 500;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 500 |
+-----------------+-------+
1 row in set (0.00 sec)
应用侧连接数过小

gormfunc Init() {
db, err := gorm.Open(mysql.Open(conn), config)
sqlDB, err := db.DB()
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(200)
// SetMaxOpenConns 设置打开数据库连接的最大数量
sqlDB.SetMaxOpenConns(1000)
}
buffer pool太小
Bytemysql> show global variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+
1 row in set (0.01 sec)
128Mbmysql> set global innodb_buffer_pool_size = 536870912;
Query OK, 0 rows affected (0.01 sec)
mysql> show global variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 536870912 |
+-------------------------+-----------+
1 row in set (0.01 sec)
怎么知道buffer pool是不是太小了?

show status like 'Innodb_buffer_pool_%';Innodb_buffer_pool_read_requestsInnodb_buffer_pool_readsbuffer pool 命中率 = 1 - (Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests) * 100%
99%还有哪些骚操作?
8.0版本
总结
- 数据查询过慢一般是索引问题,可能是因为选错索引,也可能是因为查询的行数太多。
- 客户端和数据库连接数过小,会限制sql的查询并发数,增大连接数可以提升速度。
- innodb里会有一层内存buffer pool用于提升查询速度,命中率一般>99%,如果低于这个值,可以考虑增大buffer pool的大小,这样也可以提升速度。
- 查询缓存(query cache)确实能为查询提速,但一般不建议打开,因为限制比较大,并且8.0以后的Mysql里已经将这个功能干掉了。
边栏推荐
- When does MySQL use table locks and row locks?
- Three things programmers want to do most | comics
- nVisual综合布线管理软件与网管软件的区别
- What about the new retail e-commerce platform? Can we realize the digital transformation of traditional retail enterprises?
- Shell | 查看进程的方法的不完全总结
- Function secondary development / plug-in development of JMeter (detailed version)
- OpenIM重大升级-群聊读扩散模型发布 群管理功能升级
- Kubernetes kubelet hard core knowledge architecture
- OpenCV求两个区域的交集
- 可视化机房管理
猜你喜欢

Keil errors and solutions (1): fcarm - output name not specified, please check 'options for target - Utilities‘

USB通信协议深入理解

Software configuration | pychart download, installation, environment configuration and uninstall
![[MySQL Cluster fault recovery]](/img/bf/8073831d810293170c62356757c368.png)
[MySQL Cluster fault recovery]

Récursion des bosses 1: formule récursive
![[introduction series of redis] data types and related commands of redis](/img/de/7322362f4a27acd264c29f325e45a2.png)
[introduction series of redis] data types and related commands of redis

Pymoo learning (3): use multi-objective optimization to find the set of optimal solutions

搜索二叉树——寻找节点,插入节点,删除节点

General paging implementation

食品安全|爱吃烟熏食品的注意了,这些知识你知道吗
随机推荐
蓝桥杯真题:卡片[通俗易懂]
搜索二叉树——寻找节点,插入节点,删除节点
软件配置 | Pycharm下载、安装及环境配置和卸载
Mysql: MySQL problem that is not a MySQL problem
xlinx pcie xvc
使用 Preparedstatement 选择和显示记录的 JDBC 程序
小程序商城如何精细化运营?
深度学习学习记录-优化器的学习率的更新
Pyinstaller+installforge multi file project software packaging
Kubernetes focuses on kubelet's responsibilities
In depth understanding of USB communication protocol
Pymoo学习 (2):带约束的双目标优化问题
SQL报错盲注详解
Keil errors and solutions (1): fcarm - output name not specified, please check 'options for target - Utilities‘
12 pictures +6k figure ZGC garbage collector and tuning skills
Dead beat recursion 1: recursive formula
食品安全|吃皮蛋会铅中毒?了解这几点后放心吃
Program environment and pretreatment
Encapsulate the general connection and query of the project with pymysql
Pyinstaller+InstallForge多文件项目软件打包