위탁 보고서에이 커서를 작성했습니다. 커미션이 한 테이블에오고 레코드는 다른 테이블입니다. 나는 특정 critera에 근거한 2 개를 match한다 (정확한 match가 없다). 문제는 레코드가있는 중복이 있다는 것입니다. 커미션을 records
테이블과 일치 시키면 이러한 중복을 가져올 수 있습니다. 따라서 담당자는 더 많은 돈을받습니다. 다른 한편 수수료 표에도 중복 기록이 있지만 계정이 2 개월 동안 지불되었음을 의미하는 것은 간단합니다.커서를 빠르게 만드는 방법
이 쿼리를 작성했지만 실행하는 데 5 분 이상이 걸립니다. 레코드 테이블에는 50,000 개의 레코드가 있고 커미션 테이블에는 100,000 개의 레코드가 있습니다. 이 커서를 개선하는 방법이 있습니까?
/* just preparation of cursor, this is not time consuming */
CREATE TABLE #result
(
repid INT,
AccountNo VARCHAR(100),
supplier VARCHAR(15),
CompanyName VARCHAR(200),
StartDate DATETIME,
EndDate DATETIME,
Product VARCHAR(25),
commodity VARCHAR(25),
ContractEnd DATETIME,
EstUsage INT,
EnrollStatus VARCHAR(10),
EnrollDate DATETIME,
ActualEndDate DATETIME,
MeterStart DATETIME,
MeterEnd DATETIME,
ActualUsage INT
)
DECLARE @AccountNo VARCHAR(100)
DECLARE @supplier VARCHAR(10)
DECLARE @commodity VARCHAR(15)
DECLARE @meterstart DATETIME
DECLARE @meterEnd DATETIME
DECLARE @volume FLOAT
DECLARE @RepID INT
DECLARE @Month INT
DECLARE @Year INT
SET @repID = 80
SET @Month = 1
SET @year = 2012
/* the actual cursor */
DECLARE commission_cursor CURSOR FOR
SELECT AccountNo,
supplier,
commodity,
meterStart,
MeterEnd,
Volume
FROM commission
WHERE Datepart(m, PaymentDate) = @Month
AND Datepart(YYYY, PaymentDate) = @Year
OPEN commission_cursor
FETCH next FROM commission_cursor INTO @AccountNo, @supplier, @commodity, @MeterStart, @MeterEnd, @Volume;
WHILE @@fetch_status = 0
BEGIN
IF EXISTS (SELECT id
FROM Records
WHERE AccountNo = @AccountNo
AND supplier = @supplier
AND Commodity = @commodity
AND RepID = @repID)
INSERT INTO #result
SELECT TOP 1 RepID,
AccountNo,
Supplier,
CompanyName,
[Supplier Start Date],
[Supplier End Date],
Product,
Commodity,
[customer end date],
[Expected Usage],
EnrollStatus,
ActualStartDate,
ActualEndDate,
@meterstart,
@MeterEnd,
@volume
FROM Records
WHERE AccountNo = @AccountNo
AND supplier = @supplier
AND Commodity = @commodity
AND RepID = @repID
AND @MeterStart >= Dateadd(dd, -7, ActualStartDate)
AND @meterEnd <= Isnull(Dateadd(dd, 30, ActualEndDate), '2015-12-31')
FETCH next FROM commission_cursor INTO @AccountNo, @supplier, @commodity, @MeterStart, @MeterEnd, @Volume;
END
SELECT *
FROM #result
/* clean up */
CLOSE commission_cursor
DEALLOCATE commission_cursor
DROP TABLE #result
나는 내가 무엇을 얻을 것은 테이블 형태로이 쿼리를 다시 작성입니다 위해, How to make a T-SQL Cursor faster?에 대답을 읽었습니다. 하지만 조인을 사용하고 번개가 빠른 또 다른 쿼리가 있습니다. 문제는, 내 records
테이블에있는 dups를 구별 할 수 없다는 것입니다.
제가 할 수있는 일이 더 빠릅니까? 이것은 기본적인 질문입니다. 그렇지 않다면, 그것을 할 대안이 있습니까?
은 내가 특별히가
- 하는 뷰 또는 저장 프로 시저의 도움을 사용하는 것입니다 도움이 필요보다 빠르고
- 구문에서 다른 옵션
링크 된 질문의 커서가'FAST_FORWARD' 옵션으로 선언 된 것을 알고 계셨습니까? –
그게 무슨 뜻인지 모르겠다. 그는 아마도 여기에 적용되지 않는 커서에서 커서를 사용하고있었습니다. –
커서 성능의 주요 문제점은 기본 옵션 (전역, 동적, 읽기/쓰기, 스크롤 가능)이 사용될 때입니다. 이 기사를 읽으십시오 : http://sqlblog.com/blogs/aaron_bertrand/archive/2012/01/26/the-fallacy-that-a-while-loop-isn-ta-cursor.aspx 그 뜻은 아닙니다. 'LOCAL STATIC READ_ONLY FORWARD_ONLY'을 추가하는 것은 효율성을 향상시키는 * 유일한 방법입니다 (루프없이이 작업을 수행 할 수 있습니다). 그러나 좋은 시작입니다. –