【发布时间】:2017-01-17 02:33:28
【问题描述】:
我需要提高 SQL Server 2014 中存储过程的性能。
这是我的程序,我想优化这个程序,因为它运行缓慢。
谁能用一些例子来解释一下,哪种查询在什么情况下更好?
CREATE PROCEDURE [dbo].[sp_Customer_SendMoney]
@CustomerId bigint,
@MobileNo nvarchar(15),
@Amount money,
@Comment nvarchar(250),
@PassPhrase nvarchar(50),
@Type varchar(50) = null
AS
BEGIN
DECLARE @returnCode INT
DECLARE @RetVal BIGINT, @CustomerBalance MONEY,
@CustomerMoneyRequestedId BIGINT,
@ToCustomerId BIGINT = 0,
@TransactionId BIGINT, @CustomerAccount BIGINT,
@FromCustomerBalance MONEY = 0,
@ToCustomerBalance MONEY = 0
IF EXISTS (SELECT Id FROM Customer
WHERE Id = @CustomerId AND IsDeleted = 0 AND IsActive = 1)
BEGIN
SELECT
@CustomerBalance = Balance
FROM
Customer
WHERE
Id = @CustomerId AND IsDeleted = 0 AND IsActive = 1
select @ToCustomerId = Id, @CustomerAccount = AccountNo,@ToCustomerBalance=Balance From Customer where convert(nvarchar,DecryptByPassPhrase(@PassPhrase, MobileNo)) = @MobileNo and IsDeleted = 0 and IsActive = 1
if(@ToCustomerId > 0)
begin
if( lower(isnull(@Type,'regular')) <> 'suspention')
begin
set @ToCustomerBalance=@ToCustomerBalance+@Amount
end
END
set @FromCustomerBalance=@CustomerBalance-@Amount
if((@CustomerBalance > 0) and (@CustomerBalance >= @Amount) )
Begin
BEGIN TRAN TxnsenMoney
BEGIN TRY
select @TransactionId = TransactionW2W+1 from MstGenerateTransactionID
where [year]=datepart(yyyy,getdate()) and [month]=DATENAME(month,getdate())
update MstGenerateTransactionID set TransactionW2W= @TransactionId
where [year]=datepart(yyyy,getdate()) and [month]=DATENAME(month,getdate())
--set @TransactionId = CONVERT(bigint,replace(convert(varchar, getdate(),111),'/','') + replace(convert(varchar, getdate(),114),':',''))
IF(@ToCustomerId > 0)
BEGIN
--Update sender Customer
update Customer set Balance = Balance - @Amount where Id = @CustomerId
--Update receiver Customer
if(lower(isnull(@Type,'regular')) <> 'suspention')
begin
update Customer set Balance = Balance + @Amount where Id = @ToCustomerId
end
else
begin
update Customer set SuspentionAccount = isnull(SuspentionAccount,0) + @Amount where Id = @ToCustomerId
end
INSERT INTO [TransactionW2W]
([TransactionId]
,[FromCustomerId]
,[ToCustomerId]
,[MobileNo]
,[Amount]
,[Comments]
,[CreatedOn]
,[FromCustomerBalance]
,[ToCustomerBalance])
VALUES
(@TransactionId
,@CustomerId
,@ToCustomerId
,@MobileNo
,@Amount
,@Comment
,GETDATE()
,@FromCustomerBalance
,@ToCustomerBalance)
End --end IF @ToCustomerId > 0
ELSE
BEGIN
--Update sender Customer
update Customer set Balance = Balance - @Amount where Id = @CustomerId
--print 'ELSE'
INSERT INTO [TransactionW2W]
([TransactionId]
,[FromCustomerId]
,[ToCustomerId]
,[MobileNo]
,[Amount]
,[Comments]
,[CreatedOn]
,[FromCustomerBalance])
VALUES
(@TransactionId
,@CustomerId
,@ToCustomerId
,@MobileNo
,@Amount
,@Comment
,GETDATE()
,@FromCustomerBalance)
INSERT INTO [NewCustomer]
([FromCustomerId]
,[MobileNo]
,[Amount]
,[CreatedOn]
)
VALUES
(@CustomerId
,@MobileNo
,@Amount
,GETDATE()
)
END --end ELSE @ToCustomerId > 0
print @RetVal
IF(@@TRANCOUNT >0 )
begin
set @RetVal = @TransactionId
print @RetVal
end
else
begin
RAISERROR('records not executed',16,1)
END
COMMIT TRAN TxnsenMoney
END TRY
BEGIN CATCH
ROLLBACK TRAN TxnsenMoney
set @RetVal = -1
declare @error varchar(max)
set @error= ERROR_MESSAGE()
-- RAISERROR(@error,16,1)
print @error
END CATCH
select @RetVal
End
END
End
【问题讨论】:
-
如果此过程有效但只需要优化,那么它非常适合我们的姊妹网站Code Review。
-
旁注:您应该不为您的存储过程使用
sp_前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免sp_并使用其他东西作为前缀 - 或者根本不使用前缀! -
您需要同时查看查询计划和统计信息 io 输出。您还可以使用计划缓存中的性能指标。如果您希望有人提供帮助,您还需要包含您的表和索引结构。没有任何细节,只是猜测问题出在哪里。