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

Откуда: Питер
Сообщений: 1401
Сам запрос.
SELECT     dbo.Point.PointNumber, dbo.Point.PointName, dbo.Point.PointShtamp, dbo.Tovar.TovarNomer, dbo.Naim.NaimName, dbo.Point.KeyPoint, 
                      dbo.Category.KeyCategory, dbo.Category.CategoryName, dbo.Vozvrat.VozvratDate, dbo.Vozvrat.VozvratKol, DATEPART(dy, dbo.Vozvrat.VozvratDate) 
                      AS NumDay, dbo.TovarPriceOut(dbo.Point.KeyPoint, dbo.Tovar.KeyTovar) * dbo.Vozvrat.VozvratKol AS Summa, dbo.TovarPriceOut(dbo.Point.KeyPoint, 
                      dbo.Tovar.KeyTovar) AS PriceOut
FROM         dbo.Naim INNER JOIN
                      dbo.Tovar ON dbo.Naim.KeyNaim = dbo.Tovar.TovarNaim INNER JOIN
                      dbo.Category ON dbo.Naim.NaimCategory = dbo.Category.KeyCategory INNER JOIN
                      dbo.Vozvrat ON dbo.Tovar.KeyTovar = dbo.Vozvrat.VozvratTovar INNER JOIN
                      dbo.Point ON dbo.Vozvrat.VozvratPoint = dbo.Point.KeyPoint
WHERE     (dbo.Vozvrat.VozvratDate = @inDate) AND (dbo.Vozvrat.VozvratKol > 0)
Функция которая все тормозит.
ALTER   FUNCTION [dbo].[TovarPriceOut_stuipid]
	(@inPoint as smallint,
	@inTovar as int)
RETURNS smallmoney
AS
	BEGIN
		DECLARE @OutPrice as smallmoney
		SET @OutPrice = ISNULL	((SELECT TOP 1 RashodPriceOut FROM Rashod WHERE (RashodTovar = @inTovar) AND (RashodPoint = @inPoint) ORDER BY RashodDate DESC)
					, 
						ISNULL	((SELECT Zakaz.ZakazPriceOut FROM Zakaz INNER JOIN Tovar ON Zakaz.ZakazNaim = Tovar.TovarNaim WHERE (Tovar.KeyTovar = @inTovar) AND (Zakaz.ZakazPoint = @inPoint))
							,
							(SELECT TovarPriceOut FROM Tovar WHERE (KeyTovar = @inTovar))
							)
					)
	RETURN @OutPrice
	END

  |--Compute Scalar(DEFINE:([Expr1010]=datepart(dayofyear, Convert([Vozvrat].[VozvratDate])), [Expr1011]=[dbo].[TovarPriceOut]([Point].[KeyPoint], [Tovar].[KeyTovar])*Convert([Vozvrat].[VozvratKol]), [Expr1012]=[dbo].[TovarPriceOut]([Point].[KeyPoint], [To
       |--Hash Match(Inner Join, HASH:([Category].[KeyCategory])=([Naim].[NaimCategory]))
            |--Index Scan(OBJECT:([NewPressTest].[dbo].[Category].[IX_Category]))
            |--Hash Match(Inner Join, HASH:([Point].[KeyPoint])=([Vozvrat].[VozvratPoint]))
                 |--Clustered Index Scan(OBJECT:([NewPressTest].[dbo].[Point].[PK_Point]))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([Tovar].[TovarNaim]) WITH PREFETCH)
                      |--Nested Loops(Inner Join, OUTER REFERENCES:([Vozvrat].[VozvratTovar]) WITH PREFETCH)
                      |    |--Clustered Index Seek(OBJECT:([NewPressTest].[dbo].[Vozvrat].[PK_Vozvrat]), SEEK:([Vozvrat].[VozvratDate]='Aug  5 2009 12:00AM'),  WHERE:([Vozvrat].[VozvratKol]>0) ORDERED FORWARD)
                      |    |--Clustered Index Seek(OBJECT:([NewPressTest].[dbo].[Tovar].[PK_Tovar]), SEEK:([Tovar].[KeyTovar]=[Vozvrat].[VozvratTovar]) ORDERED FORWARD)
                      |--Clustered Index Seek(OBJECT:([NewPressTest].[dbo].[Naim].[PK_Naim]), SEEK:([Naim].[KeyNaim]=[Tovar].[TovarNaim]) ORDERED FORWARD)

10 авг 09, 13:31    [7517325]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
linke
Member

Откуда: Питер
Сообщений: 1401
linke,

Вроде понятно что функция вызывается на каждую строку в запросе, при чем по два раз, но вот что с ней делать ума не приложу.
10 авг 09, 13:32    [7517329]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36808
Убрать функцию нафиг и написать обычный запрос.
10 авг 09, 13:38    [7517366]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
linke
Member

Откуда: Питер
Сообщений: 1401
Гавриленко Сергей Алексеевич,
Переписал вот так.
SELECT   dbo.Point.PointNumber, dbo.Point.PointName,
	 dbo.Point.PointShtamp, 
	 dbo.Tovar.TovarNomer,
	 dbo.Naim.NaimName,
	 dbo.Point.KeyPoint, 
         dbo.Category.KeyCategory, 
	 dbo.Category.CategoryName, dbo.Vozvrat.VozvratDate, 
	 dbo.Vozvrat.VozvratKol, 
	 DATEPART(dy, dbo.Vozvrat.VozvratDate)   AS NumDay ,
         IsNull(rashod.RashodPriceOut,isnull(zakaz.ZakazPriceOut,tovar.TovarPriceOut))* dbo.Vozvrat.VozvratKol AS Summa,
         IsNull(rashod.RashodPriceOut,isnull(zakaz.ZakazPriceOut,tovar.TovarPriceOut))AS PriceOut
FROM         dbo.Naim INNER JOIN
dbo.Tovar ON dbo.Naim.KeyNaim = dbo.Tovar.TovarNaim INNER JOIN
dbo.Category ON dbo.Naim.NaimCategory = dbo.Category.KeyCategory INNER JOIN
dbo.Vozvrat ON dbo.Tovar.KeyTovar = dbo.Vozvrat.VozvratTovar INNER JOIN
dbo.Point ON dbo.Vozvrat.VozvratPoint = dbo.Point.KeyPoint
inner   join rashod  on rashod.rashodPoint=dbo.Point.KeyPoint and  rashod.rashodtovar=tovar.keytovar
inner join zakaz on zakaz.zakazpoint=dbo.Point.KeyPoint and  zakaz.zakaznaim=tovar.tovarNaim
WHERE     (dbo.Vozvrat.VozvratDate = @inDate) AND (dbo.Vozvrat.VozvratKol > 0)
Тормозить перестало.Но количество записей меньше стало.
10 авг 09, 14:06    [7517564]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
linke
Member

Откуда: Питер
Сообщений: 1401
в принципе оно и понятно почему меньше.
10 авг 09, 14:08    [7517577]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
iap
Member

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

функция же возвращала NULL, если не было подходящих записей. И стояла в списке SELECTа.
А INNER JOIN такие записи вообще отбрасывает.
10 авг 09, 14:10    [7517589]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
linke
Member

Откуда: Питер
Сообщений: 1401
iap,

Это понятно.
10 авг 09, 14:12    [7517606]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
linke
iap,

Это понятно.
Так почему же LEFT JOIN не напишете?

Надо ещё посмотреть, не появляются ли лишние записи от того, что отношение между таблицами
многие-ко-многим, а не 1:1. Не зря же у Вас в функции TOP 1 стояло....
10 авг 09, 14:16    [7517635]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизаия запроса  [new]
linke
Member

Откуда: Питер
Сообщений: 1401
iap
linke
iap,

Это понятно.
Так почему же LEFT JOIN не напишете?

Надо ещё посмотреть, не появляются ли лишние записи от того, что отношение между таблицами
многие-ко-многим, а не 1:1. Не зря же у Вас в функции TOP 1 стояло....


Там по логике именно inner join.Функция не моя. А top 1 стоял там потому что в функции если посмотрите нету даты, а в переписанном запросе дата используется в where, а в табличке rashod PK по (RaskladDate,RaskladTovar,RaskladPoint).

Почему так было сделано понять не могу.
10 авг 09, 14:25    [7517687]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить