影刀RPA 数据库慢查询监控:慢SQL自动采集与分析
作者:林焱
什么情况用什么
线上系统突然变慢,DBA登录数据库一看——有个查询跑了30秒还没结束,把CPU打满了。这种事一个月发生好几次,每次都是用户投诉了才发现。
影刀RPA做慢查询监控的逻辑:定时连数据库 → 查慢查询日志 → 和新发现的慢SQL对比 → 新的/变慢的自动告警 → 生成优化建议。
怎么做
店群矩阵自动化突破运营极限!
第一步:采集慢查询
MySQL慢查询日志采集:
importpymysql conn=pymysql.connect(host='192.168.1.100',user='dba',password='***',database='mysql')cursor=conn.cursor()# 查询最近1小时的慢查询cursor.execute(""" SELECT start_time, user_host, query_time, lock_time, rows_sent, rows_examined, db, sql_text FROM mysql.slow_log WHERE start_time >= NOW() - INTERVAL 1 HOUR ORDER BY query_time DESC """)slow_queries=cursor.fetchall()conn.close()影刀操作:
1. 【执行Python】连接数据库,执行慢查询SQL 2. 【读取结果】将结果集存入变量第二步:慢查询去重与归类
同一个SQL模板可能产生几百条慢查询记录。
importrefromcollectionsimportCounterdefnormalize_sql(raw_sql):"""将SQL中的具体值替换为占位符,提取SQL模板"""sql=raw_sql.lower().strip()# 替换字符串字面量sql=re.sub(r"'[^']*'",'?',sql)# 替换数字sql=re.sub(r'\b\d+\b','N',sql)# 替换IN列表sql=re.sub(r'\((\s*[?N]\s*,?\s*)+\)','(?)',sql)returnsql# 统计SQL模板出现次数templates=Counter()forqueryinslow_queries:template=normalize_sql(query['sql_text'])templates[template]+=1# 输出Top 10慢查询模板fortemplate,countintemplates.most_common(10):avg_time=avg_query_time(template)print(f'出现{count}次 | 平均{avg_time:.2f}秒 |{template[:100]}')第三步:新增慢查询告警
如果出现了一个昨天没有、今天才有的慢查询,说明是新引入的问题。
# 读取昨天已记录的慢查询模板withopen(r'D:\monitor\known_slow_queries.txt','r')asf:known=set(line.strip()forlineinf)new_slows=[]fortemplate,countintemplates.items():iftemplatenotinknown:new_slows.append({'模板':template,'次数':count,'首次出现':first_seen(template),})ifnew_slows:alert='⚠️ 发现新的慢查询模板:\n'forsinnew_slows:alert+=f' - [{s["次数"]}次]{s["模板"][:80]}\n'send_alert(alert)# 更新已知慢查询列表withopen(r'D:\monitor\known_slow_queries.txt','w')asf:fortemplateintemplates:f.write(template+'\n')第四步:生成优化建议
defsuggest_optimization(sql_template):suggestions=[]if'select *'insql_template:suggestions.append('避免SELECT *,只查询需要的字段')if'like ?%'insql_templateor'like %?%'insql_template:suggestions.append('LIKE前置%无法使用索引,考虑全文搜索')if'group by'insql_templateand'order by'notinsql_template:suggestions.append('GROUP BY可能产生临时表,检查是否有索引')if'join'insql_templateand'where'notinsql_template:suggestions.append('JOIN缺少过滤条件,可能需要加索引或限制数据范围')returnsuggestionsifsuggestionselse['手动分析']有什么坑
temu店群自动化报活动案例
坑1:慢查询日志未开启
很多MySQL默认没开慢查询日志。先检查:
SHOWVARIABLESLIKE'slow_query_log%';SHOWVARIABLESLIKE'long_query_time';如果off,需要DBA开启。建议long_query_time设0.5秒(500ms)。
坑2:SQL模板归一化误判
SELECT * FROM users WHERE id = 1和SELECT * FROM users WHERE id = 99999是同一个模板。但如果SQL里有动态拼接的表名或字段名,归一化可能失败。需要更高级的SQL解析(sqlparse库)。
坑3:PROD库不能频繁查
每隔5分钟查一次慢查询日志会增加数据库负担。控制在15-30分钟一次。
坑4:只监控了查询没监控锁
有些SQL本身不慢,但因为锁等待导致响应慢(如UPDATE语句被其他事务阻塞)。监控范围要包括innodb_lock_waits表。
总结:慢查询监控的价值是"早发现"——一个今天跑了0.5秒的SQL,下个月可能因为数据量增长变成5秒。自动化帮你第一时间捕捉到这种退化。