Note:
This topic has been translated from a Chinese forum by GPT and might contain errors.Original topic: 表量级相当索引都有的情况,简单的调换表的顺序,执行效率差异很大。
[TiDB Usage Environment] Test
[TiDB Version] 6.3.0
[Encountered Problem: Phenomenon and Impact]
The execution plans differ greatly when the order of two tables with similar amounts of data is swapped. How should this be adjusted:
- JZ_MJZ_JZJL2 Clustered Index (jzxh, jzlb, yljgdm) Table Data Volume: 17,499,037 rows
- HZ_JZJBXX Clustered Index (jzxh, jzlb, yljgdm) Table Data Volume: 17,147,543 rows
Simply swapping the order,
Join statement
query1:
select ....
from JZ_MJZ_JZJL2 a
inner join HZ_JZJBXX hz on a.jzxh=hz.jzxh and a.jzlb=hz.jzlb and a.yljgdm=hz.yljgdm
where a.hzid= '728615'
query2:
select ....
from HZ_JZJBXX a
inner join JZ_MJZ_JZJL2 hz on a.jzxh=hz.jzxh and a.jzlb=hz.jzlb and a.yljgdm=hz.yljgdm
where a.hzid= '728615'
Table structure: JZ_MJZ_JZJL2
+------------------------+---------------+------+------+----------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+---------------+------+------+----------------------+-------+
| bxh | bigint(20) | NO | | NULL | |
| yljgdm | varchar(20) | NO | PRI | NULL | |
| yljgmc | varchar(50) | YES | | NULL | |
| jzxh | varchar(36) | NO | PRI | NULL | |
| jzlb | varchar(4) | NO | PRI | NULL | |
| hzid | varchar(36) | YES | MUL | NULL | |
| ghjslsh | varchar(36) | YES | | NULL | |
| ghsj | datetime(3) | YES | | NULL | |
| cfzbz | varchar(4) | YES | | NULL | |
| yyghbz | varchar(4) | YES | | NULL | |
| mzyyxh | varchar(36) | YES | | NULL | |
| ghksdm | varchar(20) | YES | | NULL | |
| ghksmc | varchar(50) | YES | | NULL | |
| ghysdm | varchar(20) | YES | | NULL | |
| ghysmc | varchar(50) | YES | | NULL | |
| ghfsdm | varchar(20) | YES | | NULL | |
| ghfsmc | varchar(50) | YES | | NULL | |
| ghlbdm | varchar(20) | YES | | NULL | |
| ghlbmc | varchar(50) | YES | | NULL | |
| txmzbz | varchar(4) | YES | | NULL | |
| ghjlzt | varchar(4) | YES | | NULL | |
| tjzxh | varchar(36) | YES | | NULL | |
| thsj | datetime(3) | YES | | NULL | |
| ghczydm | varchar(20) | YES | | NULL | |
| ghczymc | varchar(50) | YES | | NULL | |
| ghhx | varchar(20) | YES | | NULL | |
| jzztdm | varchar(20) | YES | | NULL | |
| jzztmc | varchar(50) | YES | | NULL | |
| zjscjzsj | datetime(3) | YES | | NULL | |
| zjecjzsj | datetime(3) | YES | | NULL | |
| zjzhjzsj | datetime(3) | YES | | NULL | |
| jzksdm | varchar(20) | YES | | NULL | |
| jzksmc | varchar(50) | YES | | NULL | |
| scjzysdm | varchar(20) | YES | | NULL | |
| scjzysmc | varchar(50) | YES | | NULL | |
| zhjzysdm | varchar(20) | YES | | NULL | |
| zhjzysmc | varchar(50) | YES | | NULL | |
| sfzlqj | varchar(4) | YES | | NULL | |
| sfqjcg | varchar(4) | YES | | NULL | |
| sfsw | varchar(4) | YES | | NULL | |
| termflag | varchar(4) | YES | | NULL | |
| termfailedcolumn | varchar(500) | YES | | NULL | |
| termfailedmessage | varchar(5000) | YES | | NULL | |
| termsuccesscolumn | varchar(500) | YES | | NULL | |
| source | varchar(50) | YES | | NULL | |
| source_tablename | varchar(50) | YES | | NULL | |
| source_key | varchar(500) | YES | | NULL | |
| source_keyvalue | varchar(500) | YES | | NULL | |
| isdelete | varchar(4) | YES | | NULL | |
| source_lastupdate | datetime(3) | YES | | NULL | |
| destination_lastupdate | datetime(3) | YES | | NULL | |
| timestp | varbinary(50) | YES | | NULL | |
| pch | varchar(20) | YES | | NULL | |
| title_code | varchar(50) | YES | | NULL | |
| yydm | varchar(50) | YES | | NULL | |
| ghf | decimal(5,2) | YES | | NULL | |
| fylb | varchar(32) | YES | | NULL | |
| ghrq | datetime(3) | YES | | NULL | |
| swsj | datetime(3) | YES | CURRENT_TIMESTAMP(3) | |
| trial674 | char(1) | YES | | NULL | |
+------------------------+---------------+------+------+----------------------+-------+
Table structure: HZ_JZJBXX
+------------------------+--------------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+------+---------+-------+
| bxh | bigint(20) | YES | | NULL | |
| yljgdm | varchar(50) | NO | PRI | NULL | |
| yljgmc | varchar(50) | NO | | NULL | |
| jzxh | varchar(36) | NO | PRI | NULL | |
| jzlb | varchar(4) | NO | PRI | NULL | |
| hzid | varchar(36) | YES | MUL | NULL | |
| blh | varchar(36) | YES | MUL | NULL | |
| hzxm | varchar(128) | YES | MUL | NULL | |
| jsm | varchar(255) | YES | | NULL | |
| hzxbdm | varchar(128) | YES | | NULL | |
| hzxbmc | varchar(128) | YES | | NULL | |
| hzcsrq | date | YES | | NULL | |
| hzsfzh | varchar(36) | YES | MUL | NULL | |
| hyzkdm | varchar(32) | YES | | NULL | |
| hyzkmc | varchar(128) | YES | | NULL | |
| mzdm | varchar(32) | YES | | NULL | |
| mzmc | varchar(128) | YES | | NULL | |
| gjdm | varchar(32) | YES | | NULL | |
| gjmc | varchar(128) | YES | | NULL | |
| zydm | varchar(32) | YES | | NULL | |
| zymc | varchar(128) | YES | | NULL | |
| whcddm | varchar(32) | YES | | NULL | |
| whcdmc | varchar(128) | YES | | NULL | |
| hzgzdwmc | varchar(128) | YES | | NULL | |
| hzgddh | varchar(32) | YES | | NULL | |
| hzyddh | varchar(32) | YES | | NULL | |
| hzemail | varchar(50) | YES | | NULL | |
| ynkh | varchar(36) | YES | MUL | NULL | |
| ybkh | varchar(36) | YES | MUL | NULL | |
| djsj | datetime | YES | | NULL | |
| djczydm | varchar(32) | YES | | NULL | |
| djczymc | varchar(128) | YES | | NULL | |
| jlzt | varchar(4) | YES | | NULL | |
| termflag | varchar(4) | YES | | NULL | |
| termfailedcolumn | text | YES | | NULL | |
| termfailedmessage | text | YES | | NULL | |
| termsuccesscolumn | text | YES | | NULL | |
| source | varchar(50) | YES | | NULL | |
| source_tablename | varchar(50) | YES | | NULL | |
| source_key | text | YES | | NULL | |
| source_keyvalue | text | YES | | NULL | |
| isdelete | varchar(4) | YES | | NULL | |
| source_lastupdate | datetime | YES | | NULL | |
| destination_lastupdate | datetime | YES | | NULL | |
| timestp | longblob | NO | | NULL | |
| pch | varchar(32) | YES | | NULL | |
| nl | int(11) | YES | | NULL | |
| jzdz | text | YES | | NULL | |
| yydm | varchar(50) | YES | | NULL | |
| jzcs | int(11) | YES | | NULL | |
+------------------------+--------------+------+------+---------+-------+
[Resource Configuration]
[Attachments: Screenshots/Logs/Monitoring]
Execution plan of query1
Execution plan of query2
From the images, it is clear that one uses the slowest table scan method, while the other directly uses the index and pushes down the records. The table sizes are similar, and the index matches the join keys perfectly. Why is the index invalid for query1?
Tried ANALYZE TABLE operation and forced index usage, but the speed is still very slow. Can any expert explain why?