Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Разница при выполнении селекта в функции  [new]
Degun
Member

Откуда:
Сообщений: 205
Имеется следующая функция:
ALTER FUNCTION [dbo].[fn_GetPrevTradeDateForDate] (@InputDate DATETIME)
RETURNS DATETIME 
AS
BEGIN	
	DECLARE @vTradeDate DATETIME = @InputDate
	
	WHILE (NOT EXISTS( SELECT 1 FROM Params WHERE TradeDate=@vTradeDate))
	BEGIN
		SET @vTradeDate	= DATEADD(DAY,-1,@vTradeDate)
	END	
		
	RETURN @vTradeDate	
	
END

Почему вызов этой функции следующем образом:
DECLARE @InputDate DATETIME = CONVERT(datetime,'13.01.2014',104)
SET @InputDate = dbo.fn_GetPrevTradeDateForDate(@InputDate)
PRINT @InputDate

выполняется 10 секунд, а вызов аналогичного селекта:
DECLARE @vTradeDateDATETIME = CONVERT(datetime,'13.01.2014',104)
SELECT 1 FROM Params WHERE TradeDate = @vTradeDate
PRINT @vTradeDate

выполняется 5 минут?
13 янв 14, 11:41    [15406858]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Glory
Member

Откуда:
Сообщений: 104751
Потому что в функции другие команды, чем один селект

Сообщение было отредактировано: 13 янв 14, 11:42
13 янв 14, 11:42    [15406868]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Degun
Member

Откуда:
Сообщений: 205
Что нужно сделать, чтобы отдельный селект выпонялся те же 10 секунд?
13 янв 14, 11:45    [15406893]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Glory
Member

Откуда:
Сообщений: 104751
Degun
Что нужно сделать, чтобы отдельный селект выпонялся те же 10 секунд?

Вы разницы между
EXISTS(SELECT ...)
и
SELECT
понимаете ?
13 янв 14, 11:47    [15406904]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Glory,

Поделитесь. Я тоже не понимаю, почему настолько разительное значение...
13 янв 14, 11:50    [15406921]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Glory
Member

Откуда:
Сообщений: 104751
Azvaal
Поделитесь.

Это разные запросы. И возвращают они разные результаты.
И поэтому время выполнения у них разное.
13 янв 14, 11:51    [15406930]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Glory,

есть догадка, что соль в том, что exists работает до первого положительного результата, после - выходит и отдает true.

можно намек на то, где это почитать?
13 янв 14, 11:54    [15406948]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Glory
Member

Откуда:
Сообщений: 104751
Azvaal
можно намек на то, где это почитать?

В хелпе разумеется. Открытым текстом сказано

When a subquery is introduced with the keyword EXISTS, it functions as an existence test. The WHERE clause of the outer query tests for the existence of rows returned by the subquery. The subquery does not actually produce any data; it returns a value of TRUE or FALSE
13 янв 14, 11:57    [15406967]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Degun
Member

Откуда:
Сообщений: 205
Glory,

Согласен, разница обусловлена этим. Но почему тогда выполнение этой функции для даты '13.01.2014':
DECLARE @InputDate DATETIME = CONVERT(datetime,'13.01.2014',104)
SET @InputDate = dbo.fn_GetPrevTradeDateForDate(@InputDate)
PRINT @InputDate

выполняется 10 сек., а для даты '12.01.2014':
DECLARE @InputDate DATETIME = CONVERT(datetime,'12.01.2014',104)
SET @InputDate = dbo.fn_GetPrevTradeDateForDate(@InputDate)
PRINT @InputDate

выполняется 6 минут?
При этом следующий код для даты '13.01.2014' выполняется за секунду и в переменную @IsExist возвращает значение 1:
DECLARE @vTradeDate DATETIME = CONVERT(datetime,'13.01.2014',104)
DECLARE @IsExist INT
IF EXISTS( SELECT 1 FROM Params WHERE TradeDate = @vTradeDate)
	SET @IsExist = 1
ELSE
	SET @IsExist = 0
PRINT @IsExist

а для даты '12.01.2014' выполняется за время > 10 минут и возвращает 0?
DECLARE @vTradeDate DATETIME = CONVERT(datetime,'12.01.2014',104)
DECLARE @IsExist INT
IF EXISTS( SELECT 1 FROM Params WHERE TradeDate = @vTradeDate)
	SET @IsExist = 1
ELSE
	SET @IsExist = 0
PRINT @IsExist
13 янв 14, 12:11    [15407054]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Glory
Member

Откуда:
Сообщений: 104751
Потому что для несуществующей даты серверу приходится просканировать всю таблицу.
А для существующей даты - лишь часть таблицы.
Индекса то по TradeDate наверняка нет
13 янв 14, 12:15    [15407081]     Ответить | Цитировать Сообщить модератору
 Re: Разница при выполнении селекта в функции  [new]
Degun
Member

Откуда:
Сообщений: 205
Glory,

Спасибо.
13 янв 14, 12:20    [15407134]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить