SQL 查看外部应用速度
Posted
技术标签:
【中文标题】SQL 查看外部应用速度【英文标题】:SQL View Outer Apply Speed 【发布时间】:2013-06-25 15:23:19 【问题描述】:在使用带有外部应用的视图时,我看到一些奇怪的查询速度结果,我对视图中的 2 个不同列进行了不同的计数,1 个在不到 0.1 秒内完成,另一个需要 4-6 秒,第二个计数查询是否返回较慢,因为它是外部应用的一部分?如果是这样 - 我怎样才能加快这个查询?
快速不同的计数是 -
SELECT DISTINCT ISNULL([ItemType], 'N/A') AS Items FROM vwCustomerItemDetailsFull
缓慢的不同计数是 -
SELECT DISTINCT ISNULL([CustomerName], 'N/A') AS Items FROM vwCustomerItemDetailsFull
视图是 -
SELECT I.ItemID,
IT.Name AS ItemType,
CASE
WHEN CustomerItemEndDate IS NULL
OR CustomerItemEndDate > GETDATE() THEN CustomerItems.CustomerName
ELSE NULL
END AS CustomerName,
CASE
WHEN CustomerItemEndDate IS NULL
OR CustomerItemEndDate > GETDATE() THEN CustomerItems.CustomerNumber
ELSE NULL
END AS CustomerNumber,
CASE
WHEN CustomerItemEndDate IS NULL
OR CustomerItemEndDate > GETDATE() THEN CustomerItems.CustomerItemStartDate
ELSE NULL
END AS CustomerItemStartDate,
FROM tblItems I
INNER JOIN tblItemTypes IT
ON I.ItemTypeID = IT.ItemTypeID
OUTER APPLY (SELECT TOP 1 CustomerName,
CustomerNumber,
StartDate AS CustomerItemStartDate,
EndDate AS CustomerItemEndDate
FROM tblCustomerItems CI
INNER JOIN tblCustomers C
ON C.CustomerID = CI.CustomerID
WHERE CI.ItemID = I.ItemID
ORDER BY EndDate DESC) AS CustomerItems
【问题讨论】:
很可能OUTER APPLY
永远不会在ItemType
的情况下执行,因为它不会影响结果。执行计划是什么样的?
【参考方案1】:
查看执行计划,这个速度差异一点也不奇怪,因为是outer apply而不是cross apply,而且在里面你把结果限制在top 1,说明你的outer apply没有影响关于查询结果的数量,或列ItemType
。
因此,当您从视图中选择并且不使用外部应用中的任何列时,优化器足够聪明,知道它不需要执行它。所以本质上你的第一个查询是:
SELECT DISTINCT ISNULL([ItemType], 'N/A') AS Items
FROM ( SELECT tblItems
FROM Items
INNER JOIN tblItemTypes IT
ON I.ItemTypeID = IT.ItemTypeID
) vw
而您的第二个查询必须执行外部应用。
我之前发布了一个longer answer,这也可能会有所帮助。
编辑
如果您想将查询更改为 JOIN,可以这样重写:
SELECT I.ItemID,
IT.Name AS ItemType,
CustomerName,
CustomerNumber,
CustomerItemStartDate,
FROM tblItems I
INNER JOIN tblItemTypes IT
ON I.ItemTypeID = IT.ItemTypeID
LEFT JOIN
( SELECT ci.ItemID,
CustomerName,
CustomerNumber,
StartDate AS CustomerItemStartDate,
EndDate AS CustomerItemEndDate,
RN = ROW_NUMBER() OVER (PARTITION BY ci.ItemID ORDER BY EndDate DESC)
FROM tblCustomerItems CI
INNER JOIN tblCustomers C
ON C.CustomerID = CI.CustomerID
) AS CustomerItems
ON CustomerItems.ItemID = I.ItemID
AND CustomerItems.rn = 1
AND CustomerItems.CustomerItemEndDate < GETDATE();
但是我不认为这会大大提高性能,因为您说最昂贵的部分是EndDate
上的排序,并且对于您的第一个查询,它会对性能产生负面影响,因为优化器将不再优化外部应用.
我希望提高性能的最佳方法是添加索引,而不知道您的数据大小或分布我无法准确猜测您需要的确切索引,如果您自己运行查询,显示实际执行计划 SSMS会为你推荐一个比我最好的猜测更好的索引。
【讨论】:
根据较慢选择的执行计划 - 似乎外部应用中的排序导致了 96% 的查询时间.. 在更快的情况下,外部应用是否会出现? 正确,外部apply没有应用,执行计划简单了很多。 尝试使用 where 子句为活动记录实现外连接会更快吗?以上是关于SQL 查看外部应用速度的主要内容,如果未能解决你的问题,请参考以下文章
有谁家里有群辉的么,想问下群辉在外部网络访问方便么,速度怎么样?如果是公网的IP的话速度会快多少?