我有一个SQL查询,大约需要30秒才能运行,返回1条记录。与该记录的BrandId一起运行时,CROSS APPLY中使用的函数是即时的。
SELECT b.BrandId, b.Name, ah.Type, c.ContactEmails, c.ContactNumbers, c.ContactLinks FROM @IdsToFilterBy ids JOIN dbo.AccountHandler ah ON ah.AccountHandlerId = ids.Id JOIN dbo.Brand b ON ah.RepresentedByBrandId = b.BrandId CROSS APPLY dbo.[fn_GetBrandContactDetails](b.BrandId) AS c
但是,如果我只是更改表,则会从CROSS APPLY中获取BrandId。
SELECT b.BrandId, b.Name, ah.Type, c.ContactEmails, c.ContactNumbers, c.ContactLinks FROM @IdsToFilterBy ids JOIN dbo.AccountHandler ah ON ah.AccountHandlerId = ids.Id JOIN dbo.Brand b ON ah.RepresentedByBrandId = b.BrandId CROSS APPLY dbo.[fn_GetBrandContactDetails](ah.RepresentedByBrandId) AS c <-- change here
查询现在仅需要2秒钟即可运行。当我加入时,dbo.Brand b ON cah.RepresentedByBrandId = b.BrandId我希望他们是一样的。
dbo.Brand b ON cah.RepresentedByBrandId = b.BrandId
有人可以解释为什么巨大的性能差异吗?
更新
区别在于,当我使用b.BrandId时,CROSS APPLY在整个Brand表上运行,而当我使用ah.RepresentedByBrandId时,则在整个AccountHandler表上运行。AccountHandler表要小得多。
但是,我希望CROSS APPLY只能在JOIN的结果上运行,而JOIN的结果是一个1记录。这可能吗?或者我想念CROSS APPLY吗?
找到了。
为了强制CROSS APPLY在JOIN的子结果集上运行,而不是在JOINS我使用OPTION(FORCE ORDER)之前的整个表上运行
SELECT b.BrandId, b.Name, ah.Type, c.ContactEmails, c.ContactNumbers, c.ContactLinks FROM @IdsToFilterBy ids JOIN dbo.AccountHandler ah ON ah.AccountHandlerId = ids.Id JOIN dbo.Brand b ON ah.RepresentedByBrandId = b.BrandId CROSS APPLY dbo.[fn_GetBrandContactDetails](b.BrandId) AS c OPTION (FORCE ORDER)
现在,它立即运行,并查看执行计划,该功能仅针对一个结果而不是整个db表被调用。