对同一张表做两个in查询,一个很慢,一个很快,请教大佬如何解决该问题

【SQL-1】

【SQL-2】

【SQL-1执行计划】

【SQL-2执行计划】

现在sql1中表【tbl_company_middle】中字段cluster_id已建btree索引,表【tbl_company_basic_info_rare_earth_test】中字段cluster_id和字段is_main_business已建btree索引,in中子查询返回速度很快,子查询返回记录数为400多条

sql2中表【tbl_company_middle】和sql1相同,表【tbl_company_label】中字段company_id和字段label_id已建btree索引,in中子查询返回速度很快,子查询返回记录数为11万多条

表【tbl_company_middle】总记录数为7000多万

现在sql2执行耗时:1.35秒左右
而sql1执行耗时:25秒左右

请问大佬们是什么原因导致的sql1执行耗时远大于sql2?

是做了联合索引吗

不要用in, tbl_company_middle全表扫了, 改join

在执行计划选择里面,如果TiDB 选择 “索引扫描” 或 “快速 Hash Join” 就是快速的;而TiDB 选择 “全表扫描” 或 “低效 Nested Loop Join”就是慢的

sql2 优化器进行了等价改写,增加了 group by (streamagg) 子查询去重逻辑,这样优化器可以将 semi join 改成 inner join , 进而可以利用索引走 indexlookup join。
sql1 猜测可能是由于代价估算,认为改写会代价更高。走了 semi join + hash join 的方式,tbl_company_middle 数据很多,所以会很慢。
如果 tbl_company_basic_info_rare_earth_test 表数据量较小的话,可以尝试对 sql 加个 hint 让优化器改写一下试试,https://docs.pingcap.com/zh/tidb/stable/optimizer-hints/#use_tojaboolean_value

1 个赞

第一个sql是不是存在null值

执行计划给的信息已经很详细了,有个全表扫的SQL呢

扫描全表,或者联合索引有null会导致失效