进一步优化 SQL Server 存储过程

Posted

技术标签:

【中文标题】进一步优化 SQL Server 存储过程【英文标题】:Optimize SQL Server Stored Procedure further 【发布时间】:2014-04-04 00:27:19 【问题描述】:

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

性能改进在哪里?

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

【问题讨论】:

如果这是您的代码,并且是您能想到的最好的,应该在Code Review 网站上询问。或者您是在询问一般如何优化 SP? 【参考方案1】:

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

如果不了解表结构和其他争用这些表上的锁的查询,很难给你一个具体的建议。确保 cc_testagents.ID、cc_testagents.uuid、cc_testnumbers.CallUUID 上有聚集/非聚集索引。

如果您遇到死锁问题并且从 cc_testagents/cc_testnumbers 读取的查询可以容忍读取未提交的数据,则快速而肮脏的“修复”是在这些选择语句上使用 nolock 提示/设置未提交的事务隔离级别读取。 这取决于你问的是谁,这被认为是不好的做法,如果你在生产中遇到一些严重的死锁问题,只是把它扔在那里可能会让你陷入困境。

【讨论】:

以上是关于进一步优化 SQL Server 存储过程的主要内容,如果未能解决你的问题,请参考以下文章

Sql server2014 内存优化表 本地编译存储过程

SQL Server——存储过程

SQL Server 索引重新创建存储过程慢

在SQL server中如何写存储过程

如何使用 SQL Server 通过 ETL 存储过程提取数据

SQL Server T—SQL 存储过程 触发器