我有一个复杂的报告(类似于下面的例子)它在42秒内只返回52个项目(缓慢但复杂的连接)当我执行以下操作时它会大幅减慢:
我如何理解执行是先执行where然后执行select(只应对52个结果项执行)。但是,如果我使用(1)场景运行精确的52个项目,则在外部CTE选择上使用它时,仅需要7秒与添加的150个项目。
为什么会这样,如何在没有膨胀的执行时间的情况下添加列?
CREATE FUNCTION PriorShippers
(
@customerId nchar(5)
)
RETURNS varchar(500)
AS
BEGIN
DECLARE @return varchar(500);
with data as
(
select distinct S.CompanyName from Customers C
join Orders O on C.CustomerID = O.CustomerID
join Shippers S on O.ShipVia = S.ShipperID
where C.CustomerID = @customerId
) select @return = STUFF((select CompanyName + ' ' from data FOR XML PATH('')),1,0,'')
return @return
END
查询(我使用Northwind数据库 - {2012}的Install Instructions here)
DECLARE @categories TABLE
(
Name varchar(100),
SourceCountry varchar(100)
);
insert into @categories VALUES ('Seafood', 'US');
insert into @categories VALUES ('Beverages', 'US');
insert into @categories VALUES ('Condiments', 'US');
insert into @categories VALUES ('Dairy Products', 'India');
insert into @categories VALUES ('Grains/Cereals', 'India');
with data as
(
select C.CustomerID, C.CompanyName,
(CASE WHEN EXISTS(select * from Orders O where O.CustomerID = C.CustomerID) THEN
(select count(distinct CAT.CategoryID) from Orders O
join [Order Details] OD on O.OrderID = OD.OrderID
join Products P on OD.ProductID = P.ProductID
join Categories CAT on P.CategoryID = CAT.CategoryID
where EXISTS(select * from @categories where Name = CAT.CategoryName AND SourceCountry = 'US'))
ELSE 0 END) as 'US Orders',
(CASE WHEN EXISTS(select * from Orders O where O.CustomerID = C.CustomerID) THEN
(select count(distinct CAT.CategoryID) from Orders O
join [Order Details] OD on O.OrderID = OD.OrderID
join Products P on OD.ProductID = P.ProductID
join Categories CAT on P.CategoryID = CAT.CategoryID
where EXISTS(select * from @categories where Name = CAT.CategoryName AND SourceCountry = 'India'))
ELSE 0 END) as 'India Orders'
from Customers C
) select top 10 CompanyName, [US Orders], [India Orders]
-- Below: Adding this have significant slow down
, dbo.PriorShippers(CustomerID)
from data where [US Orders] > 0 Order By [US Orders]
答案 0 :(得分:0)
您正在为每个选定的行执行用户定义的函数。简而言之,不要这样做。
直接在报告中将函数中的代码移动到DTE中。
另外,我注意到你的计数的连接是相同的。它们看起来像是第三个DTE的主要候选者,您可以简单地加入其中以进一步提高整体查询的性能。