SQL зависает, когда выполняется как SP, но хорошо как SQL - PullRequest
2 голосов
/ 06 апреля 2011

Привет, Я анализировал проблему с удаленной хранимой процедурой. Процедура просто выполняет каскадное удаление определенного объекта.

Когда я разбиваю SP на SQL в редакторе запросов, он запускается через прибл. Однако через 7 секунд, когда SP выполняется через EXEC SP, выполнение занимает более 1 минуты.

Я попробовал следующее без удачи:

  • Уронил SP и затем воссоздал его, используя WITH RECOMPILE
  • Добавлено УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ СДЕЛКИ СЧИТАЕТСЯ НЕОГРАНИЧЕННЫМ

  • SQL работает в редакторе с множеством одновременных соединений без проблем.

  • Процедура EXEC зависает с одновременными подключениями или без них

Процедура похожа на:

 ALTER PROCEDURE [dbo].[DELETE_Something]
    (
        @SomethingID INT,
        @Result INT OUT,
        @ResultMessage NVARCHAR(1000) OUT
    )--WITH RECOMPILE--!!!DEBUGGING
    AS

    --SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED--!!!DEBUGGING

    SET @Result=1
    BEGIN TRANSACTION
    BEGIN TRY

        DELETE FROM XXXXX --APPROX. 34 Records
        DELETE FROM XXXX  --APPROX. 227 Records         
        DELETE FROM XXX   --APPROX. 58 Records  
        DELETE FROM XX    --APPROX. 24 Records      
        DELETE FROM X     --APPROX. 14 Records  

        DELETE FROM A -- 1 Record
        DELETE FROM B -- 1 Record
        DELETE FROM C -- 1 Record

        DELETE FROM D --APROX. 3400 Records !!!HANGS FOR OVER ONE MINUTE TRACING THROUGH SP BUT NOT SQL

        GOTO COMMIT_TRANS   

    END TRY
    BEGIN CATCH 
        GOTO ROLLBACK_TRANS
    END CATCH       

    COMMIT_TRANS:
        SET @Result=1   
        COMMIT TRANSACTION
        RETURN  

    ROLLBACK_TRANS: 
        SET @Result=0
        SET @ResultMessage=CAST(ERROR_MESSAGE() AS NVARCHAR(1000))
        ROLLBACK TRANSACTION
        RETURN

Ответы [ 3 ]

2 голосов
/ 06 апреля 2011

Убедитесь, что ваша статистика актуальна. Предполагая, что операторы DELETE имеют некоторую ссылку на передаваемые параметры, вы можете попробовать опцию OPTIMIZE FOR UNKNOWN , если вы используете SQL 2008.

1 голос
/ 06 апреля 2011

Как и в случае любой проблемы с производительностью, вам нужно измерить , почему она «зависает».Гадание никуда не приведет вас быстро.Используйте методологический подход, такой как Ожидания и очереди .Самое простое, что можно сделать, это посмотреть wait_type, wait_time и wait_resource в sys.dm_exec_requests, для запроса, выполняющего exec sp, в то время как он выполняет sp.На основании того, что на самом деле является причиной блокировки, вы можете предпринять соответствующие действия.

1 голос
/ 06 апреля 2011

Это была скорее проблема с прослушиванием параметров (или спуфингом). Это редко используемый SP. Использование OPTION (OPTIMIZE FOR UNKNOWN) для оператора, использующего параметр для довольно большой таблицы, по-видимому, решило проблему. Спасибо SqlACID за подсказку.

DELETE FROM 
   ProblemTableWithManyIndexes
WHERE                                   
   TableID=@TableID 
OPTION (OPTIMIZE FOR UNKNOWN)
...