2012-08-10 258 views
0

我對SQL Server有以下SP。奇怪的是執行查詢過程需要很長時間才能執行查詢

Select @max_backup_session_time = Max(MachineStat.BackupSessionTime) from MachineStat  where MachineStat.MachineID = @machine_id; 

它需要1秒,如果MachineStat表中有關於@machine_id行,但如果沒有行的@machine_id那麼就需要超過半分鐘就在SP weired行爲執行。有人可以幫助我理解這一點。

SET NOCOUNT ON; 

DECLARE @MachineStatsMId TABLE (
    MachineId   INT NULL, 
    BackupSessiontime BIGINT NULL, 
    MachineGroupName NVARCHAR(128) NULL) 
DECLARE @machine_id AS INT; 
DECLARE @Machine_group_id AS INT; 
DECLARE @machine_group_name AS NVARCHAR(128); 
DECLARE @max_backup_session_time AS BIGINT; 

SET @machine_id = 0; 
SET @Machine_group_id = 0; 
SET @machine_group_name = ''; 

DECLARE MachinesCursor CURSOR FOR 
    SELECT m.MachineId, 
     m.MachineGroupId, 
     mg.MachineGroupName 
    FROM Machines m, 
     MachineGroups mg 
    WHERE m.MachineGroupId = mg.MachineGroupId; 

OPEN MachinesCursor; 

FETCH NEXT FROM MachinesCursor INTO @machine_id, @machine_group_id, @machine_group_name; 

WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SELECT @max_backup_session_time = Max(MachineStat.BackupSessionTime) 
     FROM MachineStat 
     WHERE MachineStat.MachineID = @machine_id; 

     INSERT INTO @MachineStatsMId 
     VALUES  (@machine_id, 
        @max_backup_session_time, 
        @machine_group_name); 

     FETCH NEXT FROM MachinesCursor INTO @machine_id, @machine_group_id, @machine_group_name; 
    END; 

SELECT * 
FROM @MachineStatsMId; 

CLOSE MachinesCursor; 

DEALLOCATE MachinesCursor; 
GO 
+1

爲什麼使用遊標?你爲什麼使用舊式連接? – 2012-08-10 14:36:39

+0

如果您必須使用遊標並且您沒有使用遊標執行更新或雙向移動,請將其設置爲LOCAL FAST_FORWARD。 (雖然遊標實際上並不需要) – JamieSee 2012-08-10 14:49:43

回答

1

這裏是完全避免了遊標和表變量的替代版本,使用適當的(現代)連接和前綴模式,並應該跑了很多比你有什麼更快。如果在某些情況下仍然運行緩慢,請張貼該場景的實際執行計劃以及快速場景的實際執行計劃。

ALTER PROCEDURE dbo.procname 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT 
    m.MachineId, 
    BackupSessionTime = MAX(ms.BackupSessionTime), 
    mg.MachineGroupName 
    FROM dbo.Machines AS m 
    INNER JOIN dbo.MachineGroups AS mg 
    ON m.MachineGroupId = mg.MachineGroupId 
    INNER JOIN dbo.MachineStat AS ms -- you may want LEFT OUTER JOIN here, not sure 
    ON m.MachineId = ms.MachineID 
    GROUP BY m.MachineID, mg.MachineGroupName; 
END 
GO 
+0

謝謝Aaron。它確實有幫助。 – user1590494 2012-08-14 16:33:52

相關問題