如何在SQL Server中优化此查询

时间:2015-12-30 14:33:52

标签: sql sql-server

我有以下查询:

DECLARE @codeItem VARCHAR(100);
DECLARE @Price DECIMAL(18, 5);
DECLARE @EndDate DATE;
DECLARE @StartDate DATE;

DECLARE Cur CURSOR FOR
    SELECT *
    FROM myTable

OPEN Cur

FETCH NEXT FROM Cur INTO @codeItem, @Price, @EndDate, @StartDate

WHILE @@fetch_status = 0 BEGIN

    EXEC sp_Proc @codeItem, @Price, @EndDate, @StartDate

    FETCH NEXT FROM Cur INTO @codeItem, @Price, @EndDate, @StartDate
END

CLOSE Cur
DEALLOCATE Cur

存储过程sp_Proc

UPDATE SRC
SET enddate = DATEADD(DAY, -1, @StartDate)
FROM test SRC
WHERE codeItem = @codeItem
    AND (@StartDate BETWEEN startdate AND enddate)

INSERT INTO test (codeItem, price, startdate, enddate)
VALUES (@codeItem, @price, @StartDate, @EndDate)

如何优化查询?

删除光标?

如何让它更快?

3 个答案:

答案 0 :(得分:4)

您不需要光标,也不需要存储过程。这样的事情应该有效:

update s
    set EndDate = dateadd(day, -1 , t.StartDate)
    from src s join
         mytable t
         on s.codeItem = t.codeItem and
            (t.StartDate between s.startDate and s.EndDate);

insert into test(codeItem, price, StartDate, EndDate)
    select codeItem, price, StartDate, EndDate
    from myTable;

update"关闭"以前的记录。 insert插入新的。这些是基于集合的操作,因此它们应该比使用游标快得多。

答案 1 :(得分:0)

BEGIN TRY
    BEGIN TRANSACTION

        UPDATE s
        SET enddate = DATEADD(DAY, -1, t.StartDate)
        FROM dbo.test s
        JOIN dbo.myTable t ON s.codeItem = t.codeItem
        WHERE t.StartDate BETWEEN startdate AND enddate

        INSERT INTO test (codeItem, price, startdate, enddate)
        SELECT codeItem, price, startdate, enddate
        FROM myTable

    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 BEGIN
        ROLLBACK TRANSACTION
    END
    PRINT ERROR_MESSAGE()
END CATCH

答案 2 :(得分:0)

如果使用查询比使用游标更快。

例如,对于您的更新查询,您可以使用此查询:

 Update SRC set EndDate = dateadd(day,-1, mt.StartDate)
 from test SRC 
 inner join myTable as mt
     on mt.codeItem = SRC.codeItem 
 where mt.StartDate between startDate and EndDate;

并为您插入查询

Insert Into test
select * from myTable;