MySQL慢查询风险指数模型设计( 二 )


一个慢查询如果执行时间为 1s  , 查询次数(QueryCount)为 1 和查询次数为 1000 时 , 对系统的影响不同 , 次数越多危害越大 , 量变会引发质变 。QueryCount 最正确的值是这个慢查询当天执行的的最大执行次数 。
 
但是预测未来并不可靠 , 对于线上业务没有人会准确知道下一时刻的查询次数会有多少 , 故我们使用昨天的数据 , 通过计算出单个时间窗口内的执行次数的最大值 , 来计算出这个慢查询对当前系统的影响 。单个时间窗口选取太小 , 比如 10s 、1min 等计算出来的 QueryCount 会太小 , 并不能清楚的反应指标的危害程度;如果选取太大 , 比如 30min , 1hour 会造成计算出来的 QueryCount 太大 , 显得指标的危害程度非常高 。
 
故我们选取 10min 作为一个参考值 , 通过以 10min 为窗口 , 滑动计算出 QueryCount 的最大值 , 作为慢查询评分模型的指标之一 。
 
3、查询其他各项指标
 
慢查询各项因素主要是由慢查询日志中记录的各项指标 。
 
mysql的慢查询说明 , 慢查询示例
 
# Time: 2108189:54:25# User@Host: fangyuan.qian[fangyuan.qian] @[127.0.0.1]Id: 316538768# Schema:Last_errno: 0Killed: 0# Query_time: 3.278988Lock_time: 0.001516Rows_sent: 284Rows_examined: 1341Rows_affected: 0# Bytes_sent: 35600SET timestamp=1629251665;SELECTa.ts_minAS slowlog_time,a.checksum,SUM(a.ts_cnt)AS d_ts_cnt,ROUND(SUM(a.Query_time_sum), 2)AS d_query_time,ROUND(SUM(a.Query_time_sum) / SUM(a.ts_cnt), 2) AS d_query_time_avg,a.host_maxAS host_ip,a.db_maxAS db_name,a.user_maxAS user_name,b.first_seenAS first_seen_timeFROM mysql_slowlog_192_168_0_84_3306.query_history a force index(idx_ts_min),mysql_slowlog_192_168_0_84_3306.query_review bWHERE a.checksum = b.checksumAND length(a.checksum)>=15AND ts_min >= '2021-06-04'AND ts_min < '2021-06-21'GROUP BY a.checksum; 
4、慢查询字段说明

MySQL慢查询风险指数模型设计

文章插图
 
5、选取评分项
 
其中 Time、User@Host 、Id、Schema 、Last_errno 都是描述性的信息不会造成查询变成慢查询;
 
Query_time 是真实记录慢查询的查询时间 , 查询时间越长对系统的影响越大;
 
Lock_time 是当前查询获取数据时获取记录锁而等待的时间 , 等待时间越长 , 越可能造成慢查询;
 
Rows_sent 是发送多少行数据给 client  , 同一个查询语句发送的数据行数越大 , 越可能会造成慢查询;
 
Rows_examined 是 server 层检索的数据 , 检索的数据越多 , 需要的IO和cpu资源也就越多 , 越可能造成慢查询 , 并影响服务稳定性;
 
Rows_affected 只针对修改请求 , 由于绝大部分慢查询都是 select  , 并不会修改数据 , 故此值可以忽略;
 
Bytes_sent 是发送多少字节数据给 client  , 发送的数据量越多 , 越可能会造成慢查询;
 
由于不同的表行大小不同 , 并且并不是所有列都需要返回 , 所以一个发送 10 行的数据 , 可能会比一个发送 100 行数据的查询更慢 , Rows_sent 不如 Bytes_sent 更为直观 , 故我们选取 Bytes_sent  , 忽略 Rows_sent。
 
所以 , 慢查询指标中 Query_time、Lock_time 、 Bytes_sent 、 Rows_examined 作为慢查询评分模型中的指标 。
 
综上所述 , 慢查询评分项共有五项 , 分别是QueryCount、Query_time、Lock_time、Bytes_sent、Rows_examined 。
 
评分模型可以简单描述为:
 
score=sum(评分项*权重) 
6、选取评分项边界
 
评分模型的评分项确认之后 , 为了防止单项分数过高 , 需要对评分项进行百分化 , 并且所有权重总和为 100  , 根据评分项计分模型可以算出符合增长曲线的分数 , 这样评分模型计算出来的总分数为 100  , 故需要确认每项的分数边界、权重、计分模型 。
 
只有各项的边界、权重、计分模型确认之后 , 给定一个慢查询 , 评分模型才能计算出合理的分数 。评分项的边界可以根据当前历史数据设置 。计分模型和权重可以首先进行假设 , 测试完成之后如果不符合预期则修改权重、计分模型 , 并重复测试-修改过程 , 直至测试结果符合预期 。


推荐阅读