2012-08-10 221 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

相关问题