Jamie888 Ответов: 1

Табличная переменная, вызывающая медленную производительность запроса?


Привет, у меня есть хранимая процедура, в которой я буду генерировать записи для пользователей. Но недавно пользователи сообщили, что генерация записей происходит медленно, и мы решили провести тонкую настройку самой хранимой процедуры. В моей хранимой процедуре у меня есть несколько операторов SELECT, в которых я соединю постоянную таблицу с табличной функцией(TVF), и моя обратная связь DBA мы можем еще больше улучшить производительность, просто заменив TVF табличной переменной. Пожалуйста смотрите ниже пример изменений до и после:
SELECT
	 c.CustomerName
	,c.CustomerAddress
	,c.CustomerOrderNo
FROM
	dbo.Customer AS c
	INNER JOIN dbo.utf_CustomerDetailInfoStatus('ACTIVE') AS cdi
		ON c.CustomerStatusId = cdi.CustomerStatusId


SELECT
	 c.CustomerName
	,c.CustomerAddress
	,c.CustomerOrderNo
FROM
	dbo.Customer AS c
	INNER JOIN @CustomerDetailInfoStatus AS cdi
		ON c.CustomerStatusId = cdi.CustomerStatusId


Приведенный выше пример-это всего лишь простой макет, чтобы показать изменения. Есть 5 TVF, которые я заменил табличными переменными, но после некоторого тестирования я обнаружил, что производительность еще больше ухудшилась примерно с 20 секунд до 6 минут продолжительности выполнения(оба возвращали 10k записей)! Я меняю переменные таблицы обратно в TVF, и она возвращается примерно на 20 секунд. Но мой DBA настаивает на том, что, заменив TVF табличными переменными, другие факторы, такие как блокировка таблицы, пик ввода-вывода, могут быть уменьшены, но благодаря тестированию с моей стороны результат будет не таким, как я ожидал.
Есть ли у кого-нибудь знания на этот счет?

Что я уже пробовал:

1. Сделал некоторые исследования на ТВФ против табличную переменную, но ни одной темы, где-то по моему делу здесь.

Santosh kumar Pithani

я думаю, что TVF вызывает проблемы с производительностью, поэтому попробуйте поместить код TVF для обзора, иначе примените правильный индекс к фильтру кода TVF.

Richard Deeming

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

1 Ответов

Рейтинг:
0

Santosh kumar Pithani

--if you don't have proper index on Customer,TVF i'm help less.

CREATE INDEX Customer_index(CustomerStatusId) INCLUDE(CustomerName,CustomerAddress,CustomerOrderNo);

SELECT
	 c.CustomerName
	,c.CustomerAddress
	,c.CustomerOrderNo
FROM
	dbo.Customer AS c 
	  CROSS APPLY dbo.utf_CustomerDetailInfoStatus('ACTIVE') AS cdi
		WHERE
             c.CustomerStatusId = cdi.CustomerStatusId OPTION(FAST 10);

 --try like this too

SELECT
	 c.CustomerName
	,c.CustomerAddress
	,c.CustomerOrderNo
FROM
	dbo.Customer AS c   WHERE EXISTS(
  SELECT 1 FROM  dbo.utf_CustomerDetailInfoStatus('ACTIVE') AS cdi
		WHERE
                   c.CustomerStatusId = cdi.CustomerStatusId 
                                         );