海石花47
2023 年3 月 7 日 02:26
1
【 TiDB 使用环境】生产环境
【 TiDB 版本】 v6.1
【遇到的问题:问题现象及影响】
当使用 select … from a join b on a.主键 = b.唯一建 where a.time >= xxx OR b.time >= xxx 的时候(time 都是索引),速度很慢,看了explain计划,没有用到索引合并?
具体的sql如下:
SELECT
a.uid,
CASE
WHEN a.reg_area IN ( 111, 0 ) THEN
b.quyubh ELSE a.reg_area
END reg_area,
CASE
WHEN location_area = 0
AND REGIONCODE IS NOT NULL THEN
REGIONCODE ELSE a.location_area
END location_area
FROM
`dwd`.`user_extend` a
JOIN `dwd`.`user_first_location` b ON b.zhanghao = a.uid
WHERE
a.update_time >= '2023-03-06 00:00:00' OR b.update_time >= '2023-03-06 00:00:00' ;
【附件:截图/日志/监控】
海石花47
2023 年3 月 7 日 02:28
2
OR 的情况下,执行计划如下:
Projection_9 19376062.00 root dwd.user_extend.uid, case(in(dwd.user_extend.reg_area, 912000000041844186, 0), dwd.user_first_location.quyubh, dwd.user_extend.reg_area)->Column#84, case(and(eq(dwd.user_extend.location_area, 0), not(isnull(dwd.user_first_location.regioncode))), dwd.user_first_location.regioncode, dwd.user_extend.location_area)->Column#85
└─Projection_10 19376062.00 root dwd.user_extend.uid, dwd.user_extend.reg_area, dwd.user_extend.location_area, dwd.user_first_location.quyubh, dwd.user_first_location.regioncode
└─IndexJoin_16 19376062.00 root inner join, inner:TableReader_13, outer key:dwd.user_first_location.weimaihao, inner key:dwd.user_extend.uid, equal cond:eq(dwd.user_first_location.weimaihao, dwd.user_extend.uid), other cond:or(ge(dwd.user_extend.update_time, 2023-03-06 00:00:00.000000), ge(dwd.user_first_location.update_time, 2023-03-06 00:00:00.000000))
├─TableReader_45(Build) 19376062.00 root data:Selection_44
│ └─Selection_44 19376062.00 cop[tikv] not(isnull(dwd.user_first_location.weimaihao))
│ └─TableFullScan_43 19398524.00 cop[tikv] table:b keep order:false
└─TableReader_13(Probe) 1.00 root data:TableRangeScan_12
└─TableRangeScan_12 1.00 cop[tikv] table:a range: decided by [dwd.user_first_location.weimaihao], keep order:false
你用or条件肯定是没办法先走索引的啊,如果先走了索引,过滤掉的值,能被关联到怎么办?所以肯定是先把两个表全表扫了,然后再过滤,后面过滤肯定走不了索引的
海石花47
2023 年3 月 7 日 02:52
5
所以,索引合并 的前提条件是一张表的OR查询条件吗? 多表关联下 就不会执行两个表索引合并了 是吗?
xfworld
(魔幻之翼)
2023 年3 月 7 日 02:55
6
改成先过滤,这样索引就生效了,在聚合就好了,范围小就会更快了
你改成and就能过滤了,两表关联后or条件过滤肯定用不上索引合并的
Running
(Hacker Zs58i2 Gb)
2023 年3 月 7 日 04:53
8
改用IN where a.update_time in (‘2023-03-06 00:00:00’,‘2023-03-06 00:00:00’)
海石花47
2023 年3 月 7 日 05:41
10
and 那肯定可以走索引了,那看来连表查询就是用不了 索引合并吧
海石花47
2023 年3 月 7 日 05:54
11
改了几次 感觉结果都不对。。请问下,怎么改? 我sql不太会
海石花47
2023 年3 月 7 日 05:57
12
是直接把OR 拆了,然后写成两个sql 加一个union 吗? 好像结果对了,也各自用索引了。 是这么改吗?
胡杨树旁
2023 年3 月 7 日 06:06
13
同一张表的or的话如果or前后都有索引应该是可以使用到index_merge 的,多表关联的话应该用不上
system
(system)
关闭
2023 年5 月 6 日 09:34
18
此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。