TIDB 进行批量任务时,处理速度越来越慢

  • 【TiDB 版本】:5.7.25-TiDB-v3.0.2
  • 【问题描述】:程序在进行分页批量任务时,耗时越来越久 一天数据大概在1.5千万左右,(group by,order by)完数据量在1.1千万 ,通过一系列group by,order by ,发现在开始前半小时内,数据统计很快,能统计完70%左右的数据,但是后面的30%越来越慢,一直延迟到9~10小时,甚至更长,在此过程中程序没有报错,tidb内存占用很高,没有释放,tidb相关日志也没有发现错误信息,不明白为啥执行到后面越来越慢。?可能是因为数据都汇总到了同一个时间点(零点),导致tidb不断要对已汇总完的数据重新分片,做一致性处理吗,所以越到后面数据量越多,处理的速度越慢?
  1. 测试过先把一天数据汇总到临时表,再到数据表 ,防止源数据表数据量过大,导致查询慢,结果也是出现上述情况。

  2. 测试过把一天数据按6小时分段处理,第一段6小时处理很快10分钟,第二段又出现上述情况,最后20%~30%的数据处理很慢。

  • 统计逻辑

    先删除该时间段的表数据-> select (分页10w) -> insert (批量2w)

    24小时的小时数据->汇总当天的零点数据

  • sql语句

SELECT camp_id,aff_id, aff_m_id, adv_id,adv_m_id,country_id,source_id, SUM(clicks) AS clicks,SUM(unique_clicks) AS unique_clicks, SUM(conversions) AS conversions, SUM(pay_out) AS pay_out,SUM(revenue) AS revenue,SUM(amount) as amount, SUM(pending_conversions) AS pending_conversions,0 AS pending_pay_out, SUM(pending_revenue) AS pending_revenue,SUM(pending_amount) AS pending_amount, SUM(rejected_conversions) AS rejected_conversions,0 AS rejected_pay_out, SUM(rejected_revenue) AS rejected_revenue,SUM(rejected_amount) AS rejected_amount, #{startZeroTime} AS create_time, is_back, currency,platform_id,event_id, is_private, SUM(impression) as impression,revenue_type,payout_type,sl_id,carrier_id,url_id,ai_id,async_clicks FROM ${reportDB}.${operationAllHourTB} WHERE create_time=]]>#{start} AND create_time#{end} AND is_tmp = 0 GROUP BY camp_id,aff_id, aff_m_id, adv_id,adv_m_id,country_id,source_id, currency,platform_id,event_id, is_private,revenue_type,payout_type,sl_id,carrier_id,url_id,ai_id,async_clicks ORDER BY camp_id,aff_id, aff_m_id, adv_id,adv_m_id,country_id,source_id, currency,platform_id,event_id, is_private,revenue_type,payout_type,sl_id,carrier_id,url_id,ai_id,async_clicks LIMIT #{_skiprows}, #{_pagesize}

  1. 提供的 SQL 语句有不正确的地方 WHERE create_time=]]>#{start} AND create_time#{end} AND is_tmp = 0 GROUP BY ORDER BY LIMIT #{_skiprows}, #{_pagesize}
  2. limit 越到最后会越来越慢,跟mysql 的行为一致

建议在每次都记录一下 start_time,每次都将上次 start_time 传入,这样会快一些

将一天24小时数据分段,按每6小时去查询,就是相当于每次拿上次start_time 传入。还是会出现上述问题。

第一点:是sql语句复制有点问题,没显示出来,已修改 第二天:tidb里面id不是连续的,请问下有啥好优化方案

  1. 如果按照 24小时/ 每次 6 小时 = 4 ,也就是只查询了 4 次吗?
  2. ID 不是连续的优化方案指的什么,需求什么?

我把每次分页查询,插入日志都打印出来了,发现每次分页查询时间都差不多,limit并没有影响太多性能。开始3分钟,后面翻到几十页也能保持在4分钟内。一开始从页面看数据量跑了70~80%是错误的,其实是把SUM(clicks)量大的排在前面,导致以为开始跑的快,后面跑的慢的错觉。后面直接修改limit 参数,每页100w,减少查询次数,相应统计时间大幅减少。

看起来当前问题已经解决,是吗? 而且优化后时间减少比较多? 能否写个案例分享给大家

1赞