某些执行单条语句很慢的场景

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

  1. 等MDL锁:

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

  2. 等flush:

    出现Waiting for table flush状态的可能情况是:有一个flush tables命令被别的语句堵住了,然后它又堵住了我们的select语句。

  3. 等行锁:

    由于访问id=1这个记录时要加读锁,如果这时候已经有一个事务在这行记录上持有一个写锁,我们的select语句就会被堵住。

第二类:查询慢

  1. 行数多导致的慢查询:

    mysql> select * from t where c=50000 limit 1;由于字段c上没有索引,这个语句只能走id主键顺序扫描,因此需要扫描5万行。

  2. 由于mysql的mvcc导致的慢查询:

    mysql> select * from t where id=1;虽然扫描行数是1,但执行时间却长达800毫秒。

    例如session A先用start transaction with consistent snapshot命令启动了一个事务,之后session B才开始执行update 语句。session B执行完100万次update语句后,session B更新完100万次,生成了100万个回滚日志(undo log)。

    带lock in share mode的SQL语句,是当前读,因此会直接读到1000001这个结果,所以速度很快;而select * from t where id=1这个语句,是一致性读,因此需要从1000001开始,依次执行undo log,执行了100万次以后,才将1这个结果返回。