剖析单条查询()
从结果可以看到该查询使用了三个临时表其中两个是磁盘临时表并且有很多的没有用到索引的读操作(Handler_read_rnd_next)假设我们不知道这个视图的具体定义仅从结果来推测这个查询有可能是做了多表关联(join)查询并且没有合适的索引可能是其中一个子查询创建了临时表然后和其他表做联合查询而用于保存子查询结果的临时表没有索引如此大致可以解释这样的结果
使用这个技术的时候要注意SHOW STATUS 本身也会创建一个临时表而且也会通过句柄操作访问此临时表这会影响到SHOW STATUS 结果中对应的数字而且不同的版本可能行为也不尽相同比较前面通过SHOW PROFILES 获得的查询的执行计划的结果来看至少临时表的计数器多加了
你可能会注意到通过EXPLAIN 查看查询的执行计划也可以获得大部分相同的信息但EXPLAIN 是通过估计得到的结果而通过计数器则是实际的测量结果例如EXPLAIN 无法告诉你临时表是否是磁盘表这和内存临时表的性能差别是很大的附录D 包含更多关于EXPLAIN 的内容
使用慢查询日志
那么针对上面这样的查询语句Percona Server 对慢查询日志做了哪些改进?下面是使用SHOW PROFILE一节演示过的相同的查询执行后抓取到的结果
# Time: ::
# User@Host: root[root] @ localhost []
# Thread_id: Schema: sakila Last_errno: Killed:
# Query_time: Lock_time: Rows_sent: Rows_examined:
Rows_affected: Rows_read:
# Bytes_sent: Tmp_tables: Tmp_disk_tables: Tmp_table_sizes:
# InnoDB_trx_id: E
# QC_Hit: No Full_scan: Yes Full_join: No Tmp_table: Yes Tmp_table_on_disk: Yes
# Filesort: Yes Filesort_on_disk: No Merge_passes:
# InnoDB_IO_r_ops: InnoDB_IO_r_bytes: InnoDB_IO_r_wait:
# InnoDB_rec_lock_wait: InnoDB_queue_wait:
# InnoDB_pages_distinct:
# PROFILE_VALUES … Copying to tmp table: … [omitted]
SET timestamp=;
SELECT * FROM sakilanicer_but_slower_film_list;
从这里看到查询确实一共创建了三个临时表其中两个是磁盘临时表而SHOW PROFILE看起来则隐藏了信息(可能是由于服务器执行查询的方式有不一样的地方造成的)这里为了方便阅读对结果做了简化但最后对该查询执行SHOW PROFILE 的数据也会写入到日志中所以在Percona Server 中甚至可以记录SHOW PROFILE 的细节信息
[] []