Procedure Analyze:
http://dev.mysql.com/doc/refman/5.6/en/procedure-analyse.html
Procedure Analyze是MySQL提供的一个分析结果集的接口,以帮助提供数据类型优化建议。其语法格式如下:
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements
,[max_memory
]])
max_elements(默认256)表示最多使用这么多个不同的列值来进行分析,是否可以使用ENUM类型,如果有超过这么多个不同的值,enum就不会纳入到考虑中。
max_memory(默认8192),是Analyze()为每个列分配的最大内存,用于尝试找到所有不同的列值。
例如,我们在一个普通的表上执行:
mysql> select k from sbtest99 procedure analyse()\G
*************************** 1. row ***************************
Field_name: sb1.sbtest99.k
Min_value: 12992
Max_value: 85008
Min_length: 5
Max_length: 5
Empties_or_zeros: 0
Nulls: 0
Avg_value_or_avg_length: 49996.6047
Std: 43159.4545
Optimal_fieldtype: MEDIUMINT(5) UNSIGNED NOT NULL
1 row in set (0.03 sec)
他会给出这个表上k列的详细统计信息,并在最后给出了优化的类型建议: MEDIUMINT(5) UNSIGNED NOT NULL, 由于他是基于已有的数据来作的分析,如果预期的数据在这个范围内,就可以据此做些优化。
实现
实现的逻辑还是比较简单的,主要代码在sql/sql_analyse.cc中,其实现思路是每查询得到一条记录,就进行统计。
这里简单记录下,以后要是需要对这个功能进行扩展时,可以快速定位到。
0. 返回值表的Metadata
函数: Query_result_analyse::send_result_set_metadata
// 构建列信息搜集对象(class field_info)
构建红黑数,用于快速排序和查询(红黑树描述见mysys/tree.c文件),
// 构建analyse返回的列信息(Query_result_analyse::change_columns())
1.处理数据
对应的结果集处理类为Query_result_analyse,对每条符合条件的记录,调用Query_result_analyse::send_data进行处理。
// 将不重复的数据插入到红黑树中。
// 如果超过了max_elements,则删除红黑树,不再插入其中.
// 统计信息是在处理每条记录时即时处理的,而不是完全跑完数据再整理。
2. 结果输出
调用函数Query_result_analyse::send_eof
// 设置最终的返回值
// 推荐的可优化类型(field_str::get_opt_type)
该功能从很早的版本就已经有了,从实现的角度来看,还非常粗糙,未来可以基于这个接口,来给用户提供更加智能化的优化建议。