我有两个表的简单查询。 massfehler_hardware
有50K行且没有索引。 f_produkt
在account_number,item_number,contract_number,[和其他一些列]上有38M行,聚集唯一索引
以下查询需要11秒:
select count(distinct a.serial_number)
from massfehler_hardware a
join f_produkt f
on a.account_number = f.account_number
where f.product_code = 'VOD'
有两个额外的连接条件,它会慢5倍:
select count(distinct a.serial_number)
from massfehler_hardware a
join f_produkt f
on a.account_number = f.account_number
and a.service_address_id = f.service_address_id
and a.outlet_location = f.outlet_code
where f.product_code = 'VOD'
为什么额外加入条件的影响如此极端?仅使用account_number加入已经将结果数量限制为大约46K,因此额外的连接条件(service_address_id和outlet_location)应该仅在那些46K行上运行,并且不应该增加太多的成本。我错过了什么?
奇怪的是,当我比较执行计划时,运行速度更快的查询的估计相对成本更高! (57%)
以下是两个执行计划:
答案 0 :(得分:0)
简短的回答是,您的查询正在强制数据库执行更多工作。它必须应用两个新的过滤器,即使它选择了最佳执行,未索引的varchar比较也可能很慢。在优化查询方面,您应该使用EXISTS
而不是JOIN
。使用JOIN
时,数据库必须处理每一行,但由于您只需要非常计数,因此EXISTS
语句通常应该更快。看看这个查询的解释计划是什么样的。
SELECT COUNT(DISTINCT a.serial_number)
FROM massfehler_hardware a
WHERE EXISTS(SELECT 1 FROM f_produkt f
WHERE a.account_number = f.account_number AND
a.service_address_id = f.service_address_id AND
a.outlet_location = f.outlet_code AND
f.product_code = 'VOD')