MySQL 微秒慢查询补丁

原文出自:The new cool MySQL patch has landed! Check your queries performance!,本文做只部分翻译。

MySQL微秒慢查询(microtime slow query)补丁包具有以下特色:

  • 识别连接

  • 每个慢查询结果中都记录了是哪个连接线程引起的,如下:

# Thread_id: 571

  • 微秒计数

  • 可以记录执行时间在1秒一下的慢查询,选项 long_query_time 的单位现在是微秒,而不是秒,例如设置成300000表示0.3秒。

    # Query_time: 0.021752  Lock_time: 0.000016  Rows_sent: 1  Rows_examined: 103
    
  • 记录复制产生的慢查询

  • 通常情况下,MySQL并不记录复制产生的慢查询,使用该补丁后,只需要打开选项 --log-slow-slave-statements 解决这一问题。

  • 详细的查询执行计划

  • 每次查询的执行计划都不一样。可能使用索引扫描,或者全表扫描,或者使用临时表。通常这些信息也能从 EXPLAIN 结果中得到。该补丁会在日志中显示了查询中最重要的几个方面,如下:

    1.  # QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: Yes  Tmp_table_on_disk: No
    2.  # Filesort: Yes  Filesort_on_disk: No  Merge_passes: 0
    

    QC_Hit 表示本次查询是否命中了查询缓存(Query Cache)。如果显示的是 0,则表示该查询并没有真正的执行。
    如果 Full_scan 的结果为 Yes 表示该查询比较糟糕,因为需要扫描全表。
    Full_join 表示联合查询时没有使用索引。
    如果需要创建临时表,则 Tmp_table 的结果为 Yes;如果需要创建基于磁盘的临时表而不是基于内存的,则 Disk_tmp_table 的值为 Yes
    如果用到 filesort 算法,则 Filesort 的值为 Yes,Filesort_on_disk 则表示排序是基于临时文件进行的。

  • InnoDB 的使用

  • 最后一部分是InnoDB使用结果的统计。MySQL现在允许运行 SHOW SESSION STATUS 来查看每个线程的统计信息,但是这并不包括InnoDB的使用,因为InnoDB部分而总是显示全局统计的结果。该补丁允许你查看每次查询的InnoDB资源使用情况。

    #   InnoDB_IO_r_ops: 3  InnoDB_IO_r_bytes: 49152  InnoDB_IO_r_wait: 0.018690
    #   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
    #   InnoDB_pages_distinct: 7
    

    InnoDB_IO_r_ops 统计计划需要读取的页数。实际数量可能不太一样,虽然它可以异步完成,不幸的是并没有好办法来衡量它。它的单位是字节(bytes)。
    InnoDB_IO_r_wait 中可以看到 InnoDB 从存储引擎中读取数据锁等待的时间(单位是秒)。
    InnoDB_rec_lock_wait 表示等待行锁所需时间(单位是秒)。
    InnoDB_queue_wait 表示等待进入 InnoDB 队列或在队列中等待执行所消耗的时间(单位是秒)。
    InnoDB_pages_distinct 显示了读取的独立页个数。这只是基于用小哈希数组表示的整个缓冲池的近似值,因为有可能需要用很大的内存来映射所有页。同一个查询却产生不准确的读取页数量增长可能是发生了哈希冲撞的缘故。
    如果查询中没有用到InnoDB,则相关日志行变成下面这样,其他的不变:

    # No InnoDB statistics available for this query
    

    注意:尽管该补丁已经做过压力测试,并且还在实际环境中使用过,但仍然建议不要在非常重要的系统中使用,万一出了问题,人家可不负责啊 :)