进一步优化SQL Server存储过程

时间:2014-04-04 00:27:19

标签: sql sql-server database tsql race-condition

如何进一步优化/重构此存储过程?

性能改进在哪里?

ALTER PROCEDURE cc_test_setnumber
    @UUID AS VARCHAR(50),
    @Status AS VARCHAR(50)
AS
BEGIN
    SET NOCOUNT ON;
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE    

    IF @Status = 'ACTIVE'  
    BEGIN
       DECLARE @Tbl AS TABLE (UUID VARCHAR(50))

       BEGIN TRANSACTION 

       UPDATE dbo.cc_testagents 
       SET Status = 'INCALL', LastUpdated = GETDATE() 
       OUTPUT INSERTED.UUID INTO @Tbl
       WHERE ID = (SELECT TOP 1 ID FROM dbo.cc_testagents WHERE Status = 'IDLE')    

       UPDATE cc_testnumbers 
       SET Status = 'ACTIVE', 
           AgentUUID = (SELECT UUID FROM @Tbl) 
       OUTPUT INSERTED.AgentUUID AS 'UUID'
       WHERE CallUUID = @UUID   

       COMMIT TRANSACTION
END  
ELSE --BUSY, WRAPUP, NOANSWER, NOAGENT
BEGIN      
       UPDATE dbo.cc_testagents  
       SET Status = 'WRAPUP' 
       WHERE UUID = (SELECT AgentUUID FROM dbo.cc_testnumbers WHERE CallUUID = @UUID)

       SELECT @Status = REPLACE(@Status, 'NOAGENT', 'IDLE')

       UPDATE dbo.cc_testnumbers 
       SET Status = @Status, CallUUID = '' 
       WHERE CallUUID = @UUID
    END 
END

1 个答案:

答案 0 :(得分:0)

在sql server management studio中,"数据库引擎调优顾问"是一个很好的起点 - 不仅适用于此存储过程,还适用于针对这些表运行的任何其他查询。

如果不了解更多关于表结构以及争用这些表上的锁的其他查询,很难给出具体建议。确保cc_testagents.ID,cc_testagents.uuid,cc_testnumbers.CallUUID上有聚簇/非聚簇索引。

如果您遇到死锁问题,并且有从cc_testagents / cc_testnumbers读取的查询可以容忍读取未提交的数据,那么快速而肮脏的修复"是在那些select语句中使用nolock提示/设置事务隔离级别read uncommitted。 根据你的要求,这被认为是不好的做法,如果你在生产中遇到一些严重的死锁问题,就把它扔掉那里可能会阻碍你。