2017-01-16 4 views
0

мне нужно улучшить производительность OFA хранимой процедуры в SQL Server 2014.SQL оптимизации запросов сервера для хранимой процедуры

Вот моя процедура, и я хочу оптимизировать эту процедуру, потому что это работает медленно.

Может кто-нибудь объяснить с некоторыми примерами, какой вопрос лучше по сравнению с чем и в какой ситуации?

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 @[email protected][email protected] 
     end 
     END 

     set @[email protected]@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 
+0

Если эта процедура работает, но только нуждается в оптимизации, то это было бы очень хорошо подходят на нашем дочернем сайте [Code Review] (http://codereview.stackexchange.com/). –

+0

Боковое примечание: вы не должны ** использовать префикс 'sp_' для ваших хранимых процедур. Microsoft [зарезервировала этот префикс для собственного использования (см. * Именование сохраненных процедур *)] (http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx) и вы рискуете столкнуться с именем когда-нибудь в будущем. [Это также плохо для производительности вашей хранимой процедуры] (http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix). Лучше просто просто избегать 'sp_' и использовать что-то еще в качестве префикса - или никакого префикса вообще! –

+0

Вам необходимо изучить как план запроса, так и статистику io. Вы также можете использовать показатели производительности из кеша плана. Если вы хотите, чтобы кто-то помог, вам также необходимо включить структуру таблиц и индексов. Без каких-либо подробностей это просто догадывается, где проблема. –

ответ

-1
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 ,@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 WITH(NOLOCK) where Id = @CustomerId and IsDeleted = 0 and IsActive = 1) Begin  

       select @CustomerBalance = Balance from Customer WITH(NOLOCK) where Id = @CustomerId and IsDeleted = 0 and IsActive = 1 
       select @ToCustomerId = Id, @CustomerAccount = AccountNo,@ToCustomerBalance=Balance From Customer WITH(NOLOCK) 
       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 @[email protected][email protected] 
        END 
       END 

     SET @[email protected]@Amount 

     if((@CustomerBalance > 0) and (@CustomerBalance >= @Amount))  
     Begin  
      BEGIN TRAN TxnsenMoney 
        BEGIN TRY 
        SELECT @TransactionId = TransactionW2W+1 
        FROM MstGenerateTransactionID WITH(NOLOCK) 
        WHERE [year]=datepart(yyyy,getdate()) and [month]=DATENAME(month,getdate()) 

        update MstGenerateTransactionID set TransactionW2W= @TransactionId 
        where [year]=YEAR(GETDATE()) and [month]= 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])  

     SELECT  @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])  

      SELECT @TransactionId ,@CustomerId ,@ToCustomerId ,@MobileNo ,@Amount ,@Comment ,GETDATE() ,@FromCustomerBalance 

      INSERT INTO [NewCustomer]  
        ([FromCustomerId] ,[MobileNo] ,[Amount] ,[CreatedOn])  

      SELECT @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 
+0

Hii Radha Я сделал WITH (NOLOCK) Изменения на Table.It позволит вам получить быстрый, если какой-либо блокировки их на столе –

+0

Использование NOLOCK, как правило, плохая идея. У него могут быть разные виды нежелательных побочных эффектов –

+0

ДА Джеймс З Но временно я решил дать решение –