为什么我只查一行的语句,也执行这么慢

19 | 为什么我只查一行的语句,也执行这么慢?

需要说明的是,如果 MySQL 数据库本身就有很大的压力,导致数据库服务器 CPU 占用率很高或 ioutil(IO 利用率)很高,这种情况下所有语句的执行都有可能变慢,不属于我们今天的讨论范围。

为了便于描述,我还是构造一个表,基于这个表来说明今天的问题。这个表有两个字段 id 和 c,并且我在里面插入了 10 万行记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;

delimiter ;;
create procedure idata()
begin
declare i int;
set i=1;
while(i<=100000)do
insert into t values(i,i);
set i=i+1;
end while;
end;;
delimiter ;

call idata();

第一类:查询长时间不返回

select * from t where id=1;
一般碰到这种情况的话,大概率是表 t 被锁住了。接下来分析原因的时候,一般都是首先执行一下 show processlist 命令,看看当前语句处于什么状态。

等 MDL 锁
出现 这个状态表示的是,现在有一个线程正在表 t 上请求或者持有 MDL 写锁,把 select 语句堵住了。

等 flush
mysql> select * from information_schema.processlist where id=1;
Waiting for table flush

等行锁
mysql> select * from t where id=1 lock in share mode;

–怎么查出是谁占着这个写锁。如果你用的是 MySQL 5.7 版本,可以通过 sys.innodb_lock_waits 表查到。
mysql> select * from t sys.innodb_lock_waits where locked_table='test'.'t'\G

第二类:查询慢

mysql> select * from t where c=50000 limit 1;

References

[1] 19 | 为什么我只查一行的语句,也执行这么慢?