为什么查询性能会随着其他连接条件而减少

时间:2015-11-16 17:33:15

标签: sql-server performance join sql-server-2005 query-optimization

我有两个表的简单查询。 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%)

以下是两个执行计划:

运行查询速度更快: Faster running query

运行较慢的查询: Slower running query

1 个答案:

答案 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')