Как сравнить производительность двух версий функции?

dba.stackexchange https://dba.stackexchange.com/questions/523

  •  16-10-2019
  •  | 
  •  

Вопрос

Я только что видел определение этой функции:

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
return  case when 
        not exists (Select * from t1 where t1.col1 = @a)
        AND @b > 0
        then 1 else 0 end
end
GO

Видя не существует Я думал , внимание полное сканирование таблицы и попытался улучшить его

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
return  case when 
        exists (Select * from t1 where t1.col1 = @a)
        OR @b > 0
        then 0 else 1 end
end

GO

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

Прокомментируйте ответ Игоря: (сравнение исправлено благодаря комментарию Matts)

Это вдохновляет меня на следующее:

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
 IF @b <= 0
   RETURN 0

 IF exists (Select * from t1 where t1.col1 = @a)
   RETURN 0

  RETURN 1
end
GO
Это было полезно?

Решение

Одна вещь, которую вы могли бы сделать для сравнения этих двух версий, - переименовать одну из них в f_old и выполнить их обе внутри одного пакета, включив при этом фактический план выполнения и статистику ввода-вывода.После этого остается просто сравнить планы и статистику ввода-вывода каждого из них.

Одна вещь, которой вам нужно опасаться, - это то, что в вашем первом утверждении у вас было IF @b > 0.В вашем втором утверждении у вас есть IF @b < 0.Что произойдет, если @b = 0?Вы не предусмотрели такую возможность.

Наконец, я полагаю, вы обнаружите, что ваши мысли относительно NOT EXISTS vs.СУЩЕСТВУЕТ - это правильно.EXISTS будет обрабатываться до тех пор, пока не будет выполнено условие.НЕ СУЩЕСТВУЕТ, требуется сканирование таблицы (если она не проиндексирована) и сканирование индекса (если проиндексирована).На маленькой таблице вы не увидите огромного прироста производительности, но всегда лучше проектировать свою логику на основе EXISTS, а не NOT EXISTS.

Мэтт

Другие советы

Я почти уверен, что SQL Server рассчитал Select * from t1 ... сначала, и только затем проверьте, существует ли результат или нет. Если это правда, то обе версии должны быть по существу идентичны быстро. Интересно, сможете ли вы проверить это, запустив эти функции на двух больших таблицах, и посмотреть, есть ли последовательно иначе в то время, которое требуется, чтобы функции вернулись?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top