【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
纯白镇的小智
(Ti D Ber Qm Qja01 M)
4
在执行计划选择里面,如果TiDB 选择 “索引扫描” 或 “快速 Hash Join” 就是快速的;而TiDB 选择 “全表扫描” 或 “低效 Nested Loop Join”就是慢的
nobody
(不定时出现)
5
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 个赞
lmdb
( : " One day my life will end, and you will wear the crown.")
7
执行计划给的信息已经很详细了,有个全表扫的SQL呢
独善其身
(Ti D Ber Bi Rqfz5 K)
9
走的执行计划都不一样,肯定是不同的效率,如果实在有要求可以使用hint固定的方法
sonomx
(Ti D Ber Ny Pjt054)
11
tbl_company_basic_info_rare_earth_test的cluster_id有空值吗,加hint走索引看看
sql1的执行计划走全表扫描了慢就慢在这里,检查下sql1子查询有null值吗,也检查下关联字段类型一致吗
第一个是全表扫描,第二个有用到索引。IN中的数据量太大回表成本太高,试试强制指定索引对比下成本大小有没有降低,如果是就是统计信息不准的问题了。