请问Tidb如何查询影响CPU负载的慢SQL

假如监控控制台打不开,如果从tidb数据库中查询慢SQL,在tidb log中可以看到慢查询日志,但是分辨不好是不是慢以及对当前CPU负载影响最大的SQL。

现在发现tikv负责都很高。

直接去数据库里面show processlist看当前哪些sql最慢,大概率就是导致cpu高的慢sql

show processlist里面的SQL多,查询语句时间显示是0,没有具体的耗时秒数,如何定位是不是慢SQL呢?

一个是看执行最慢的,如果时间都显示0那可能不是某个sql导致的,看看哪一类sql最多,然后看执行计划是不是有问题,比如小表全表扫描这种执行不慢但是比较耗费资源的

直接去数据库里面show processlist看当前哪些sql最慢,大概率就是导致cpu高的慢sql

tidb 有官方监测工具,可以看到慢SQL查询记录,还可以查看高频sql记录

Dashboard 看看Top sql

查询正在执行中的慢sql

SELECT 
    CASE WHEN TIME >= 3600 THEN CONCAT(ROUND(TIME/3600,1),'h')
         WHEN TIME >= 60 THEN CONCAT(ROUND(TIME/60,1),'min')
         ELSE CONCAT(ROUND(TIME,1),'s') END 已执行时间,
    CASE WHEN MEM >= 1024*1024*1024 THEN CONCAT(ROUND(MEM/(1024*1024*1024),1),'GiB')
         WHEN MEM >= 1024*1024 THEN CONCAT(ROUND(MEM/(1024*1024),1),'MiB')
         WHEN MEM >= 1024 THEN CONCAT(ROUND(MEM/1024,1),'KiB')
         ELSE CONCAT(ROUND(MEM,1),'B') END 最大内存,
    TxnStart 开始时间,INFO 执行语句,ID 进程号
FROM INFORMATION_SCHEMA.CLUSTER_PROCESSLIST 
WHERE COMMAND != 'Sleep'
ORDER BY TIME DESC

查询执行完的慢sql

SELECT 
    CASE WHEN Query_time >= 3600 THEN CONCAT(ROUND(Query_time/3600,1),'h')
         WHEN Query_time >= 60 THEN CONCAT(ROUND(Query_time/60,1),'min')
         ELSE CONCAT(ROUND(Query_time,1),'s') END 总执行时间,
    CASE WHEN Mem_max >= 1024*1024*1024 THEN CONCAT(ROUND(Mem_max/(1024*1024*1024),1),'GiB')
         WHEN Mem_max >= 1024*1024 THEN CONCAT(ROUND(Mem_max/(1024*1024),1),'MiB')
         WHEN Mem_max >= 1024 THEN CONCAT(ROUND(Mem_max/1024,1),'KiB')
         ELSE CONCAT(ROUND(Mem_max,1),'B') END 最大内存,
    Query 执行语句,INSTANCE TiDB实例,DB 数据库,
    TIDB_PARSE_TSO(Txn_start_ts) 开始时间,
    DATE_FORMAT(Time,'%Y-%m-%d %H:%i:%s') 结束时间
FROM information_schema.cluster_slow_query t
WHERE Time >= '2025-06-03 10:20:00'
AND Time < '2025-06-03 23:00:00'
ORDER BY Query_time DESC

不要用show processlist,那个只是当前连的tidb server的,你应该查这个,多查看看
select * from information_schema.CLUSTER_PROCESSLIST t
where t.COMMAND<>‘Sleep’
and time >0

另外参考上面的information_schema.cluster_slow_query查询

有时候tikv cpu负载都会冲到500多。

你好,请问这人查询结果是总的执行时间,可以查到单条SQL语句执行时间或平均时间吗?有时候一条语句会被执行很多次,看平均时间会比较准确。

通过命令可以查看show processlis

show processlist 这个命令不行的,只能看出进程和SQL,但看不出是哪个SQL执行慢。也看不出消耗CPU最多的是什么SQL。

用户可以通过查询information_schema.slow_query表来查看慢查询日志内容,或者通过TiDB Dashboard的慢查询页面进行查看

按照这个字段Digest汇总,然后求平均值就可以了,这个字段相同的,就是一类语句。

我们不看平均值,因为平均值不靠谱。比如平均工资~ :yum:
建议看最大、最小和中位数。

:sweat_smile: Top SQL也不靠谱, tidb topsql是按累计时间算的,根本不准。
比如: 一条SQL单独执行需要1分钟,只执行一次。
另一条SQL单独执行需要1秒,执行了1000次。
Tidb会把这个执行1000次1秒的计为Top 慢SQL.

对,不能单看一个,得都看才行

这个好,收藏~