Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Здраствуйте,
Составил запрос, в котором используется 4 одинаковых джойна (за разный период каждый)
+

DECLARE @DateBeg datetime	SET @DateBeg = '01.07.2013'
DECLARE @DateEnd datetime	SET @DateEnd = '28.07.2013'

SELECT
	TSuper.LastName AS Supervisor,
	TEmp.LastName AS Employee,
	dbo.tblCustomers.RecordID,
	COUNT(TUsrDates1.UsrDate) AS UsrCount1,
	COUNT(TUsrDates2.UsrDate) AS UsrCount2,
	COUNT(TUsrDates3.UsrDate) AS UsrCount3,
	COUNT(TUsrDates4.UsrDate) AS UsrCount4
FROM 
	dbo.tblCustomers
	INNER JOIN
	TEmp ON TEmp.EmployeeID = dbo.tblCustomers.EmployeeID
	INNER JOIN
	TSuper ON TSuper.EmployeeID = TEmp.SupervisorID
	INNER JOIN
	(	SELECT ...
	) AS TUsrID ON TUsrID.RecordID = dbo.tblCustomers.RecordID
	LEFT OUTER JOIN
	(	SELECT	*
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= @DateBeg
				AND UsrDate < DATEADD(DAY, 7, @DateBeg)
				AND DATEADD(DAY, 7, @DateBeg) <= @DateEnd
	) AS TUsrDates1 ON TUsrDates1.UsrID = TUsrID.UsrID
	LEFT OUTER JOIN
	(	SELECT	*
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= DATEADD(DAY, 7, @DateBeg)
				AND UsrDate < DATEADD(DAY, 14, @DateBeg)
				AND DATEADD(DAY, 14, @DateBeg) <= @DateEnd
	) AS TUsrDates2 ON TUsrDates2.UsrID = TUsrID.UsrID
	LEFT OUTER JOIN
	(	SELECT	*
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= DATEADD(DAY, 14, @DateBeg)
				AND UsrDate < DATEADD(DAY, 21, @DateBeg)
				AND DATEADD(DAY, 21, @DateBeg) <= @DateEnd
	) AS TUsrDates3 ON TUsrDates3.UsrID = TUsrID.UsrID
	LEFT OUTER JOIN
	(	SELECT	*
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= DATEADD(DAY, 21, @DateBeg)
				AND UsrDate <= @DateEnd
	) AS TUsrDates4 ON TUsrDates4.UsrID = TUsrID.UsrID
WHERE
	TEmp.FirstName IS NOT NULL
GROUP BY
	TSuper.LastName,
	TEmp.LastName,
	dbo.tblCustomers.RecordID


Запрос выполняется 40 секунд (!)
Однако, если убрать один из LEFT джойнов и оставить любые три - запрос выполняется за секунду

Смотрел планы... но я в них не силён и понял только что они абсолютно разные и во втоорм случае используется некая опция "Буферизировать индекс" с 3000000 повторами и стоимостью 50%

Подскажите, есть ль возможность ускорить запрос?
13 авг 13, 13:34    [14701966]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Glory
Member

Откуда:
Сообщений: 104760
Bryk_Alien
Подскажите, есть ль возможность ускорить запрос?

Заменить все LEFT OUTER JOIN на CASE внутри агрегатных функций
13 авг 13, 13:37    [14701989]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
точно...

Спасибо за вариант!

А чем запрос с 3 одинаковыми джойнами отличается от запроса с тремя? Неужели такая большая разница?
13 авг 13, 13:42    [14702039]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Glory
Member

Откуда:
Сообщений: 104760
Bryk_Alien
А чем запрос с 3 одинаковыми джойнами отличается от запроса с тремя? Неужели такая большая разница?

Для вашего пищеварения есть разница употребить 3 или 4 одинаковых котлеты ?
Котлеты одинаковые, чего это вы 4ю котлету едите дольше 3ей ?
13 авг 13, 13:44    [14702066]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Glory
Заменить все LEFT OUTER JOIN на CASE внутри агрегатных функций

+1005000
13 авг 13, 13:46    [14702085]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Glory
Bryk_Alien
А чем запрос с 3 одинаковыми джойнами отличается от запроса с тремя? Неужели такая большая разница?

Для вашего пищеварения есть разница употребить 3 или 4 одинаковых котлеты ?
Котлеты одинаковые, чего это вы 4ю котлету едите дольше 3ей ?
Имхо неудачный пример... сравнили жопу с пальцем
13 авг 13, 14:07    [14702266]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Александр52
Member

Откуда: Кокосовые острова ส็็็็็
Сообщений: 5133
Bryk_Alien, попробуйте добавить в конец
option(force order)
тем самым,вы укажете оптимизатору брать таблицы именно в том порядке, в каком вы их записали.
Не говорю что это будет априори быстрее, но попробовать стоит.
13 авг 13, 14:26    [14702417]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Cammomile
Member

Откуда:
Сообщений: 1214
Bryk_Alien
А чем запрос с 3 одинаковыми джойнами отличается от запроса с тремя? Неужели такая большая разница?
Чем 3 яблока отличаются от 4 яблок? А 3 дома от 4 домов?

Но это лирика, а точный ответ вам даст кнопка Include Actual Execution Plan.
13 авг 13, 14:30    [14702461]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3626
Александр52
Bryk_Alien, попробуйте добавить в конец
option(force order)
тем самым,вы укажете оптимизатору брать таблицы именно в том порядке, в каком вы их записали.
Не говорю что это будет априори быстрее, но попробовать стоит.

правильный ответ уже был.... не надо сбивать товарища с пути
13 авг 13, 14:50    [14702628]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
Maxx
Glory
Заменить все LEFT OUTER JOIN на CASE внутри агрегатных функций

+1005000

один то left join можно оставить - чо уж вы такие жадные
DECLARE @DateBeg datetime	SET @DateBeg = '01.07.2013'
DECLARE @DateEnd datetime	SET @DateEnd = '28.07.2013'

SELECT
	TSuper.LastName AS Supervisor,
	TEmp.LastName AS Employee,
	dbo.tblCustomers.RecordID,
	SUM(CASE WHEN UsrDate >=@DateBeg AND UsrDate< DATEADD(DAY, 7, @DateBeg) THEN 1 ELSE 0 END) AS UsrCount1,
	SUM(CASE WHEN UsrDate >=DATEADD(DAY, 7, @DateBeg) AND UsrDate< DATEADD(DAY, 14, @DateBeg) THEN 1 ELSE 0 END) AS UsrCount2,
	SUM(CASE WHEN UsrDate >=DATEADD(DAY, 14, @DateBeg) AND UsrDate< DATEADD(DAY, 21, @DateBeg) THEN 1 ELSE 0 END) AS UsrCount3,
	SUM(CASE WHEN UsrDate >=DATEADD(DAY, 21, @DateBeg) THEN 1 ELSE 0 END) AS UsrCount4,
FROM 
	dbo.tblCustomers
	INNER JOIN
	TEmp ON TEmp.EmployeeID = dbo.tblCustomers.EmployeeID
	INNER JOIN
	TSuper ON TSuper.EmployeeID = TEmp.SupervisorID
	INNER JOIN
	(	SELECT ...
	) AS TUsrID ON TUsrID.RecordID = dbo.tblCustomers.RecordID

	LEFT OUTER JOIN dbo.tblConsUsrDates TUsrDates
	ON  TUsrDates.UsrID = TUsrID.UsrID
	AND UsrType = 0
	AND UsrDate BETWEEN  @DateBeg AND @DateEnd  
WHERE
	TEmp.FirstName IS NOT NULL
GROUP BY
	TSuper.LastName,
	TEmp.LastName,
	dbo.tblCustomers.RecordID
13 авг 13, 14:55    [14702677]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
2 Александр52,

Спасибо, но ускорить запрос не удалось...

2 Cammomile

Кнопку жал... Но видимо не хватает знаний чтобы в них разобраться. Буду смотреть вечером интернет.
Планы абсолютно разные.
В "медленном случае" фильтр и "Буферизировать индекс (Eager Spool)"
В "быстром случае" активно юзается нечто под название "параллелизм"
причём в быстром случае на всех иконках в плане 2 стрелочки, отсутствующие в медленном:

К сообщению приложен файл. Размер - 7Kb
13 авг 13, 15:10    [14702800]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
LexusR,

Спасибо, я так и сделал. Работает - быстро!
13 авг 13, 15:12    [14702815]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Впринципе причину, я, наверное, понял...

В "Быстром случае" джойнится запрос (таблица, у которой есть предикат) - то есть там уже отобранные записи в условии WHERE
А в медленном случае джойнится таблица целиком (3 млн записей, 4 раза) и только потом уже выполняется условие в пункте WHERE

Можно ли SQL заставить джойнить уже отобранные записи, как в быстром случае?
13 авг 13, 15:31    [14702989]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Вставил в подзапросы SELECT DISTINCT - тем самым, видимо, заставив их отрабатывать до операции LEFT OUTER JOIN
Отработало за секунду))))
+

DECLARE @DateBeg datetime	SET @DateBeg = '01.07.2013'
DECLARE @DateEnd datetime	SET @DateEnd = '28.07.2013'

SELECT
	TSuper.LastName AS Supervisor,
	TEmp.LastName AS Employee,
	dbo.tblCustomers.RecordID,
	COUNT(TUsrDates1.UsrDate) AS UsrCount1,
	COUNT(TUsrDates2.UsrDate) AS UsrCount2,
	COUNT(TUsrDates3.UsrDate) AS UsrCount3,
	COUNT(TUsrDates4.UsrDate) AS UsrCount4
FROM 
	dbo.tblCustomers
	INNER JOIN
	TEmp ON TEmp.EmployeeID = dbo.tblCustomers.EmployeeID
	INNER JOIN
	TSuper ON TSuper.EmployeeID = TEmp.SupervisorID
	INNER JOIN
	(	SELECT ...
	) AS TUsrID ON TUsrID.RecordID = dbo.tblCustomers.RecordID
	LEFT OUTER JOIN
	(	SELECT DISTINCT	UsrID, UsrDate
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= @DateBeg
				AND UsrDate < DATEADD(DAY, 7, @DateBeg)
				AND DATEADD(DAY, 7, @DateBeg) <= @DateEnd
	) AS TUsrDates1 ON TUsrDates1.UsrID = TUsrID.UsrID
	LEFT OUTER JOIN
	(	SELECT DISTINCT	UsrID, UsrDate
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= DATEADD(DAY, 7, @DateBeg)
				AND UsrDate < DATEADD(DAY, 14, @DateBeg)
				AND DATEADD(DAY, 14, @DateBeg) <= @DateEnd
	) AS TUsrDates2 ON TUsrDates2.UsrID = TUsrID.UsrID
	LEFT OUTER JOIN
	(	SELECT DISTINCT	UsrID, UsrDate
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= DATEADD(DAY, 14, @DateBeg)
				AND UsrDate < DATEADD(DAY, 21, @DateBeg)
				AND DATEADD(DAY, 21, @DateBeg) <= @DateEnd
	) AS TUsrDates3 ON TUsrDates3.UsrID = TUsrID.UsrID
	LEFT OUTER JOIN
	(	SELECT DISTINCT	UsrID, UsrDate
		FROM	dbo.tblConsUsrDates
		WHERE	UsrType = 0
				AND UsrDate >= DATEADD(DAY, 21, @DateBeg)
				AND UsrDate <= @DateEnd
	) AS TUsrDates4 ON TUsrDates4.UsrID = TUsrID.UsrID
WHERE
	TEmp.FirstName IS NOT NULL
GROUP BY
	TSuper.LastName,
	TEmp.LastName,
	dbo.tblCustomers.RecordID


Спасибо всем за советы!
13 авг 13, 15:37    [14703044]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Glory
Member

Откуда:
Сообщений: 104760
Bryk_Alien
Вставил в подзапросы SELECT DISTINCT - тем самым, видимо, заставив их отрабатывать до операции LEFT OUTER JOIN

Человек-оптимизатор детектед.
13 авг 13, 15:41    [14703064]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Александр52
Member

Откуда: Кокосовые острова ส็็็็็
Сообщений: 5133
Ivan Durak, это бонус к написанному выше ответу.
13 авг 13, 15:50    [14703121]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Glory
Bryk_Alien
Вставил в подзапросы SELECT DISTINCT - тем самым, видимо, заставив их отрабатывать до операции LEFT OUTER JOIN

Человек-оптимизатор детектед.
Вы так говорите, как будто это что-то плохое...
13 авг 13, 15:51    [14703126]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Glory
Member

Откуда:
Сообщений: 104760
Bryk_Alien
Glory
пропущено...

Человек-оптимизатор детектед.
Вы так говорите, как будто это что-то плохое...

Что "это" ? Заявление о том, как именно поступает оптимизатор ?
13 авг 13, 15:53    [14703137]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Glory
Bryk_Alien
пропущено...
Вы так говорите, как будто это что-то плохое...

Что "это" ? Заявление о том, как именно поступает оптимизатор ?
Было такое заявление?
13 авг 13, 15:56    [14703162]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Glory
Member

Откуда:
Сообщений: 104760
Bryk_Alien
Glory
пропущено...

Что "это" ? Заявление о том, как именно поступает оптимизатор ?
Было такое заявление?

А для чего цитирование тогда используют ? Я лично - для указания конкретной фразы/предложения
13 авг 13, 15:58    [14703174]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Empirical
Member

Откуда:
Сообщений: 99
Интересно, а outer apply начальный план улучшит?
13 авг 13, 16:01    [14703195]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Glory,

Я уже потерял нить беседы...
На проблему были даны несколько работающих ответов и она была решена. Если у Вас есть что-либо добавить, я выслушаю, если нет - я перестаю следить за темой, у меня есть более важные дела.
13 авг 13, 16:02    [14703204]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Glory
Member

Откуда:
Сообщений: 104760
Bryk_Alien
Если у Вас есть что-либо добавить, я выслушаю, если нет

Лучше всего о плане выполнения сообщает сам сервер. А не ваш мозг.
Вы как в запросе без DISTINCT, так и с DISTINCT не знаете, что и в каком порядке делает сервер.
Тем не менее делаете выводы
13 авг 13, 16:06    [14703232]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
Bryk_Alien
Guest
Empirical
Интересно, а outer apply начальный план улучшит?
Я с таким раньше не сталкивался, сейчас прочитал в справке но не понял, как его можно применить
13 авг 13, 16:06    [14703234]     Ответить | Цитировать Сообщить модератору
 Re: 4 LEFT JOIN'а  [new]
StarikNavy
Member

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

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


вам пытаются намекнуть, что ваша фраза "тем самым, видимо, заставив их отрабатывать до операции LEFT OUTER JOIN" чуть менее, чем полностью (на 146%) некорректна.
и что для вас было бы неплохо разобраться , как оно на самом деле
13 авг 13, 16:20    [14703340]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить