Проблемы с производительностью при вызове хранимого процесса из хранимого процесса - PullRequest
2 голосов
/ 24 сентября 2010

Я работал над проектом, который имел следующее требование:

TableA - родительская таблица.Когда бы ни обновлялись какие-либо дочерние записи таблицы А, поле «LastActivityDate» в таблице А должно обновляться с текущей датой UTC.

Теперь я знаю, что есть много способов сделать это.Мой пост НЕ о многих различных способах, которыми это может быть достигнуто.

Я первоначально предложил использовать триггеры для этого требования, и наши администраторы баз убили меня, потому что они не хотят триггеров в этой БД (я не знаюпочему, и это не важно для моего вопроса).Я закончил тем, что создал сохраненный процесс, единственной целью которого было обновить TableA.LastActivityDate.Затем я закодировал хранимые процедуры обновления / вставки дочерних элементов TableA для вызова этого хранимого процесса.Так, например, сохраненный процесс дочернего обновления будет выглядеть так:

Create Procedure TableB_UPD
(
 @TableBId INT
 @TableBName VARCHAR(30)
)
AS
BEGIN
 UPDATE dbo.TableB
 SET TableBName = @TableBName
 WHERE
  (TableBId = @TableBId)

 DECLARE @TableAId INT
 SELECT
  @TableAId = TableAId
 FROM
  dbo.TableB
 WHERE
  (TableBId = @TableBId)

 EXEC dbo.TableA_LastActivityDate_UPD @TableAId
END

Это довольно простой код, я называю хранимый процесс dbo.TableA_LastActivityDate_UPD из хранимого процесса TableB_UPD.Когда наши администраторы увидели это, они отказались разрешить это в своей базе данных.Они сказали мне, что при вызове хранимой процедуры внутри хранимой процедуры наблюдается огромный скачок производительности.Мне не удалось найти хороших онлайн-статей, подтверждающих это утверждение (и администраторы баз данных тоже не смогли мне их дать).

Я видел такой код во многих базах данных и никогдаслышал о каких-либо проблемах с производительностью до сих пор.У меня такой вопрос: может кто-нибудь объяснить проблемы с производительностью вокруг этого типа кода?Я был бы очень признателен за ссылки на статьи.

Это в SQL Server 2005.

Ответы [ 5 ]

3 голосов
/ 24 сентября 2010

Я с @mike, с вашим кодом не должно быть проблем. Для меня это звучит так, как будто они что-то слышали или видели что-то, и это стало законом. Вместо этого докажите им, что ваш код работает. Спросите у них тестовый экземпляр и позвольте ему летать.

3 голосов
/ 24 сентября 2010

Если есть сомнения, посмотрите на планы выполнения и SQL Profiler, чтобы убедиться, что ваши процедуры работают оптимально.Они могут рассказать вам больше о ситуации, чем мы когда-либо могли.

Единственная проблема, которую я могу подумать, касающаяся вложенных хранимых процедур, которые могут даже считаться проблемой удаленно, - это обработка ошибок во вложенных хранимых процедурах с транзакциями, но выпохоже, что это не происходит здесь.И действительно, мой пример - это скорее случай «Напишите свою хранимую процедуру должным образом».

Как бы то ни было, вложенные хранимые процедуры, являющиеся «огромным ударом по производительности», являются новостью для меня, и я уверен, что могу »Тоже ничего не поддерживающего.

2 голосов
/ 24 сентября 2010

Вложенные хранимые процы работают нормально.Мы используем их практически постоянно в условиях срочного хранения данных.У нас есть прокси, которые вызывают прокси, которые вызывают прокси для форматирования всех данных в месячном цикле, как только мы получим их от наших клиентов.

Нет снижения производительности, если вы выполняете это таким образом или запускаете проксы напрямую или запускаете ихв качестве запросов - мы провели обширное тестирование эффективности практически по всем нашим процедурам.

Исходя из вашего вопроса, вы можете работать с совершенно некомпетентными администраторами баз данных.Немного знаний - опасная вещь.

1 голос
/ 24 сентября 2010

В вашем решении о вложении вызовов процедур нет ничего плохого.Но чтобы успокоить ваших администраторов баз данных, почему бы просто не написать инструкцию update для обновления LastActivityDate в процедуре, которая обновляет таблицу B?

Я уверен, что немного дублированного кода будет наименьшей из ваших проблем вэта база данных

0 голосов
/ 25 сентября 2010

Независимо от производительности, я бы сделал это по-другому, за одну транзакцию и проще:

Create Procedure TableB_UPD
(
 @TableBId INT
 @TableBName VARCHAR(30)
)
AS
BEGIN
 SET XACT_ABORT ON;
 BEGIN TRAN;
 UPDATE dbo.TableB
 SET TableBName = @TableBName
 WHERE
  (TableBId = @TableBId)

 UPDATE dbo.TableA
 SET LastActivityDate = CURRENT_TIMESTAMP
 WHERE
  (TableBId = @TableBId)

 COMMIT;
END
...