복잡한 보고서 (아래 예제와 유사)를 사용하면 42 초 만에 52 개 항목 만 반환됩니다. (느리지 만 복잡한 결합은 있습니다.) 다음과 같이하면 속도가 크게 느려집니다. 외부 선택의 작업에 대한 CTE 쿼리 속도가 크게 저하되었습니다.
- 가 결과에 각 항목을 항목의 직렬화 된 목록을 가져 외부 선택의 열을 추가 (1백50초 추가) - 기능을 참조하십시오.
- 결과를 변수 테이블에 삽입합니다 (120 초 추가).하지만 평면화를 적용하면 (1) 문제는 줄어들지 만 시가는 줄이지 않기를 바랍니다.
내가 어떻게 실행을 이해한다는 점은 선택에서 논리가 처음 실행되고 논리가 실행된다는 것입니다 (52 개 결과 항목에 대해서만 수행되어야 함). 그러나 (1) 시나리오로 정확히 52 개의 항목을 실행하면 바깥 쪽 CTE 선택시을 사용할 때 추가 된 150 초에 비해 7 초 밖에 걸리지 않습니다.
왜 이렇게 될 수 있으며 확장 된 실행 시간없이 열을 추가 할 수 있습니까?
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
쿼리 (I는 Northwind 데이터베이스를 사용 - Install Instructions here를 SQL 2012)
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]
안녕하세요, Mike, 함수가 CTE (serialize해야하는 고유 선택)를 사용하기 때문에 선택 항목을 중첩 할 수 없습니다. 나는 함수를 호출하는 것이 일반적으로 좋은 생각이 아니라는 것을 이해하지만, 내 관심사는 실행 시간의 엄청난 증가라고한다. 만약 내가 같은 결과 (52) 항목을 CTE와 마찬가지로 가변 테이블 선택 호출 사용자 기능에 추가하면 7 초와 추가 150 초가 소요됩니다. 또한 값을 선택하는 것만으로 (사용자 함수 호출없이) 예제에서 경험 한 120 초가 추가됩니다. CTE 외부 선택이 정상 선택과 다른 점을 이해하려고합니다. –