left join非常慢,求大佬指点优化

explain analyze 之后的,estRows 和 actRows 差距大不大,如果很大的话,先解决表健康度的问题,在重新跑跑看

loops:19, index_task: {total_time: 8.89s, fetch_handle: 187.4ms, build: 391.9µs, wait: 8.7s}, table_task: {total_time: 45.5s, num: 213, concurrency: 5}

这个处理不是下推计算,直接是 tidb 循环了 19 次,通过index 找到行标识后,通过标识在获取的行记录
遍历了17315 条记录…

想要优化的话,得费点心思了

我先梳理梳理哈。
SQL:

FROM
    history_wti_alarm AS h
        LEFT JOIN
    vehicle_profile AS p ON h.vehicle_id = p.id
        LEFT JOIN
    const_wti AS c ON h.wti_code = c.wti_code
WHERE
    h.start_time >= '2022-11-01 00:00:00'
        AND h.start_time < '2022-11-02 02:00:00'
        AND h.alarm_tag = 0
ORDER BY h.start_time DESC
LIMIT 20;

主表history_wti_alarm 约18亿分区表。
满足条件的数据在p42分区,该分区6kw数据。
| remote_vehicle_prod | history_wti_alarm | p42 | 2022-11-25 10:37:23 | 12419 | 61910958 |

主表过滤后数据4169713。



主要时间花费在根据时间过滤完数据后按时间排序,取20条。

 └─TopN_99(Probe)    | 20.00      | 17315   
 | cop[tikv]  | time:43.6s, loops:424, 
 cop_task: {num: 5204, max: 347ms, min: 353.2µs, avg: 12.5ms, p95: 93.5ms, max_proc_keys: 20285, p95_proc_keys: 6771, tot_proc: 55.6s, tot_wait: 1.62s, rpc_num: 5204, rpc_time: 1m5s, copr_cache_hit_ratio: 0.00}, 
 tikv_task:{proc max:337ms, min:0s, p80:1ms, p95:86ms, iters:9005, tasks:5204}, 
 scan_detail: {total_process_keys: 4164712, total_process_keys_size: 1564260996, total_keys: 4374855, 
 rocksdb: {delete_skipped_count: 1, key_skipped_count: 3680023, 
 block: {cache_hit_count: 27810055, read_count: 2117, read_byte: 38.1 MB}}}  
 | remote_vehicle_prod.history_wti_alarm.start_time:desc, offset:0, count:20   

另外一个问题,你这个建表SQL没发错的话,下面这两组索引不是重复了吗?

  PRIMARY KEY (`alarm_id`,`start_time`) /*T![clustered_index] NONCLUSTERED */,
  UNIQUE KEY `uniq_alarm_id` (`alarm_id`,`start_time`),


  KEY `idx_start_time` (`start_time`),
  KEY `idx_end_time` (`start_time`),

使用覆盖索引,过滤后的结果排序 效果会更理想一些吧

select 列很多,覆盖是覆盖不了。可以加个(alarm_tag,start_time)组合索引看看。

tidb现在好像不支持降序索引哈。不然可以这样建:
alter table history_wti_alarm add index idx01(alarm_tag,start_time desc);

又加了个条件啊?之前发的没有code这个

大佬有什么优化的思路吗?

大佬,这里确实有点问题

大佬再指点下思路呗

优化方向还是有的:

  1. 优先获取结果后,在考虑 join

  2. 限定结果获取的范围,尽量命中索引

  3. 二级索引不如一级索引,效率上肯定 pointGet 和 batchGet 更高(点查)

  4. id 是否是递增的,如果是,order By id 就可以了

  • 最后的话,还可以拆分查询,让查询更有效

我的硬件在sql执行时,cpu ,内存都很空闲,有没有这一块的思路

上 tiflash 么? 可以考虑试试 :see_no_evil: 不知道效果怎么样

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。