У меня очень длинная хранимая процедура с несколькими блоками логики в ней, которые вставляются в разные таблицы. Вот один такой блокУточнение запроса к хранимой процедуре заставляет его работать очень медленно
У меня следующую таблицу с уникальным ограничением на
[id] [int] IDENTITY(1,1) NOT NULL
[data] [varchar](512) NULL
Этот блок попыток «данные», чтобы вставить значение «данные». если это значение уникально, оно вставлено. Во всех случаях соответствующий идентификатор данных возвращается
BEGIN TRY
INSERT INTO Data SELECT @data;
END TRY
BEGIN CATCH
END CATCH
SET @data_id = (SELECT id FROM Data WHERE data = @data);
Когда я включаю этот блок кода в моей первоначальной хранимой процедуры, она прекрасно работает. Однако, ради аккуратности I и DRY, я думал, что я абстрактный его к югу от процедуры, так как тот же блок называется в нескольких другом SPs
ALTER PROCEDURE [dbo].[q_Data_TryInsert]
@data nvarchar(512),
@id INT OUTPUT
AS
BEGIN
BEGIN TRY
INSERT INTO Data SELECT @data;
END TRY
BEGIN CATCH
END CATCH
SET @id = (SELECT id FROM Data WHERE data = @data);
END
тогда я называю эту абстрактную SP, как так что
EXEC [q_Data_TryInsert] @data, @data_id OUTPUT
Отремонтированный SP замедляет весь процесс на несколько порядков, даже если код тот же.
Почему это происходит?
У вас никогда не должно быть исключения «ловить» в вашем нормальном логическом потоке. (Таким образом, почему это называется «исключение» .. оно должно быть исключительным (редким). Положите проверку наличия внутри вашего INSERT. »If not exists (выберите null из Data, где data = @data) begin/* insert here */END. – granadaCoder
Ю. может захотеть также взглянуть на scope_identity, это избавит вас от необходимости выбрать @id –
Что показывает план выполнения как самый медленный элемент в медленном запросе? –