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();
不同场景的情况
1.查询长时间不返回
mysql> select * from t where id=1;
一般这种情况是表t被锁住了,查询错误时,一般执行show processlist命令,查看当前语句处于什么位置
等MDL锁
出现这种状态表示,现在有一个线程正在表t上请求或者持有MDL写锁,把select语句堵住了。
这类问题的处理方式是,找到谁持有MDL写锁,找到就kill掉。
等flush
另一种查询被堵住的情况
mysql> select * from information_schema.processlist where id=1;
执行完之后查看线程状态为Waiting for table flush 表示现在有一个线程在做flush操作
一般有两种flush操作用法
flush tables t with read lock;
flush tables with read lock;
等行锁
等行锁的时候就是因为连接被断开的时候,会自动回滚这个连接里面正在执行的线程。因此解决办法就是kill这个线程。
第二类,查询慢
mysql> select * from t where c=50000 limit 1;
因为c字段没有索引,因此只能走主键顺序扫描,因此需要扫描50000行。
坏查询不一定是慢查询
mysql> select * from t where id=1;
这个是一致性读,需要执行undo log将结果执行到才返回。因此数据越长越慢
mysql> select * from t where id=1 lock in share mode
这是当前读,只需要读当前的值,不需要执行undo log ,因此加了锁还比较快
问题
mysql> CREATE TABLE table_a
(
id
int(11) NOT NULL,
b
varchar(10) DEFAULT NULL,
PRIMARY KEY (id
),
KEY b
(b
)
) ENGINE=InnoDB;
假设现在表里面,有 100 万行数据,其中有 10 万行数据的b的值是‘1234567980’,执行语句
mysql> select * from table_a where b=‘1234567890abcd’;