第一类:查询长时间不返回
SELECT * FROM t WHERE id = 1;情况一 :等 MDL 锁

使用 show processlist 命令查看 Waiting for table metadata lock 的示意图。
出现这个状态表示的是,现在有一个线程正在表 t 上请求或持有 MDL 写锁,把 select 语句堵住了。
例如下面的情况:
| session A | session B |
|---|---|
| lock table t write; | |
| select * from t where id = 1; |
这类问题的处理方式,就是找到谁持有 MDL 写锁,然后把它 kill 掉。
但是,由于在 show processlist 的结果里面,session A 的 Command 列是 “Sleep”,导致查找起来很不方便。不过有了 performance_schema 和 sys 系统库以后,就方便多了。(MySQL 启动时需要设置 performance_schema=on)
通过查询 sys.schema_table_lock_waits 这张表,我们就可以直接找出造成阻塞的 process id,把这个连接用 kill 命令断开即可。

等 flush
SELECT * FROM information_schema.processlist WHERE id=1;
这个状态表示的是,现在有一个线程正要对表 t 做 flush 操作。MySQL 里面对表做 flush 操作的用法,一般有以下两个:
flush tables t with read lock;
flush tables with read lock;这两个 flush 语句,如果指定表 t 的话,代表的是只关闭表 t;如果没有指定具体的表名,则表示关闭 MySQL 里所有打开的表。
但是正常这两个语句执行起来都很快,除非它们也被别的线程堵住了。所以,出现 Waiting for table flush 状态的可能情况是:有一个 flush tables 命令被别的语句堵住了,然后它又堵住了我们的 select 语句。
偶尔比较慢
1, 数据库更新数据时是在内存中更新数据,并将更新的数据写到 redolog 中,最后再持久化到磁盘中。如果数据库一直很忙,没有将 redolog 更新到磁盘中,那么待到 redolog 大小达到限额时,数据库会停下来先将 redolog 持久化到磁盘。没有解决方法
2, 该语句一时半会一直没拿到锁,因此一直在等待。没有解决方法
一直很慢
1, 字段没有索引,走的全表查询,建立索引。
2, 字段有索引但是没用上,包括,where 中计算语句、函数使用、联合索引第一个为范围查找,更改语句或修改索引顺序等。
3, 系统选错索引了,根据内置优化,以为索引 a 合适,但是实际索引 b 更合适。