1) 先搞清楚时间到底花在哪里&&为什么时间会花在那 (show profile)
1.1 ) 主要工具和方法就是profiling
1.2 ) 整个性能优化,应该花90%的时间在测量上面,只有这样才能够对症下药
1.3 ) 通过show profile 可以知道,时间都花在哪里
1.4 )通过session级别的status,可以知道为什么时间会花在那里
flush status;
select xx from tt where ff ;
show status where variable_name like
2) 完成一项任务的时间分两个部分 执行时间和等待时间
如何优化执行时间呢 --比较简单?
2.1) 降低子任务数量
2.2) 降低子任务的执行频率
2.3) 提升子任务的执行效率并且判断任务在什么时间执行最长
如何优化等待时间呢 --比较复杂?
2.4) 一般是由于资源竞争导致,要用合适的工具找到竞争点。
2.5) 判断任务在什么地方被阻塞的时间最长。
3) 通过slow,可以找到值得优化的SQL
awk
3.1) 执行总时间最多的SQL
3.2) 单条SQL执行时间最多的SQL
4) 三种轻量级别的SQL抓取 show processlist & tcpdump & slow-query 解析工具可以用:pt-query-digest 解析tcpdump和slow query
msyql -e
5) 找到最需要优化的SQL后,可以开始跟踪分析单条SQL来获得更加底层实际的东 西,目前最好的三种方法是a)show profile b)show status c)slow query条目
a)show profile
SQL> set profiling=1;
SQL> select * from table;
SQL> show profiles;
SQL> show profile for query 1;
格式化输出:
SQL> set @query_id = 1;
SQL> SELECT STATE,SUM(DURATION) AS Total_R,
ROUND(
100*SUM(DURATION) /
(SELECT SUM(DURATION)
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID = @query_id
), 2) AS Pct_R,
COUNT(*) AS CallS,
SUM(DURATION) / COUNT(*) AS "R/CALL"
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID = @query_id
GROUP BY STATE
ORDER BY Total_R DESC;
当然,通过show profile 可以知道时间主要花在什么地方,但是你不知道为什么 会花在那些地方?这是时候就必须要跟踪堆栈来找到进一步的原因了。
查看是否使用了磁盘临时表还是内存临时表:
flush status;
sql;
show status where variable_name like
b) show status
SQL> 句柄计数器 handler counter,临时文件,表计数器
SQL> flush status ; 刷新绘画级别的状态值。
SQL> select * from table;
SQL> show status where variable_name like
6. 监控点 -- 通过监控状态数据可以发现哪些地方是异常的,然后再具体分析异 常时间点的日志。
a)show global status; --开销比较低
b)show processlist | grep state; 或者使用innotop --开销比较低
c)slow query + pt-query-digest
d)show innoDB status;
e) vmstat
f) iostat
7. 关于索引统计
发生过一件事情,show table status看到的大小100M,但是实际物理大小10G,通过这个发型索引统计有的时候非常不准确
这里简单介绍下:
innodb_stats_persistent=on , db重启后不会清空,不需要重新收集
innodb_stats_persistent=off, db重启后统计信息清空,需要重新收集统计
1、针对是否持久化统计信息mysql可以通过innodb_stats_persistent参数来控制
2、针对统计信息的时效性,mysql通过innodb_stats_auto_recalc参数来控制是否自动更新
3、针对统计信息的准确性,mysql通过innodb_stats_persistent_sample_pages 参数来控制更新
4、mysql通过analyze table 语句来手动的更新统计信息
5、mysql> select * from innodb_table_stats; last_update可以查看索引统计的最后更新时间
6、当索引统计不准确的时候,可以通过analyze table来更新索引统计信息,让执行计划更加准确。
如果这样做后,执行计划还是不准确,那么可以试图调大innodb_stats_persistent_sample_pages,让索引页收集的更加多,让执行计划更准确
8. 关于索引选择性: 字段1 building_id,字段2 status
单索引字段的索引选择性: select count(distinct building_id)/count(*) as selectivity from community_units;
组合索引的索引选择性: select count(distinct (concat(building_id,status)))/count(*) as selectivity from community_units;
组合前缀的索引选择性: select count(distinct (concat(building_id,left(status,2))))/count(*) as selectivity from community_units;
得到的结果越接近1,效果越好