Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
При LEFT JOIN данный запрос исполняется 15 сек, если же заменяю на INNER JOIN - то 0,5-1 сек
(fi_* функции в запросе - это InLine-функции, каждая из них по отдельности выполняется за милисекунды)

А мне надо именно LEFT JOIN. Как тут можно выкрутиться???



SELECT .....
FROM @actualCompany a
INNER JOIN Company c ON a.id_company=c.id_company
INNER JOIN dbo.fi_WithOnePrnt() r ON c.id_a=r.id_a
LEFT JOIN dbo.fi_GetCompanyStaff(@dateActual) m ON
a.id_company=m.id_company
WHERE a.id_prntCompany=0
ORDER BY c.briefName
5 мар 04, 09:48    [564860]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Вообщето LEFT OUTER всегда медленнее INNER...
А, вообще то, план покажи.
5 мар 04, 09:54    [564878]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
Алексей Ельцов
Member

Откуда: Redmond
Сообщений: 252
Глупый вопрос - значение dbo.fi_GetCompanyStaff(@dateActual) ведь не меняется в течении запроса, верно?

Тогда почему бы не попробовать заранее вычислить это значение, запихать в переменную и использовать вместо функции ?

Если это не помогает или не подходит - планы запросов в студию...
Алексей
5 мар 04, 09:56    [564886]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
и условие a.id_prntCompany=0 можно попробовать в первый же джойн засунуть, иначе при left join оптимизатор может не понять - что к чему..
5 мар 04, 10:03    [564903]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
Sa
Member

Откуда: Ekaterinburg
Сообщений: 4019
Тут надо бить запрос и во что бы то нистало избавляться от Left Join. Может через дополнительную таблицу попробывать. Сначала туда добавить значения

SELECT .....
FROM @actualCompany a
INNER JOIN Company c ON a.id_company=c.id_company
INNER JOIN dbo.fi_WithOnePrnt() r ON c.id_a=r.id_a

а затем из leftа.

Ну вообще надо попробывать несколько вариантов.

2 superbluesman
Неплохо запрос тэгами SRC окружать
5 мар 04, 10:12    [564930]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
Crip
Member

Откуда:
Сообщений: 2490
2Sa
Тут надо бить запрос и во что бы то нистало избавляться от Left Join
Чем это вам left join не угодил? Планы надо смотреть, а не догматику разводить...
5 мар 04, 10:30    [564974]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
Sa
Member

Откуда: Ekaterinburg
Сообщений: 4019
>Чем это вам left join не угодил? Планы надо смотреть, а не догматику разводить...

Чем не угодил во первых:
1) >При LEFT JOIN данный запрос исполняется 15 сек, если же заменяю на INNER JOIN - то 0,5-1 сек

2) Практика а не догматика. Была подобная ситуация разрулил при помощи дополнительной таблицы как и писал выше.

Но время покажет как лучше поэтому ждем экспериментов автора.
5 мар 04, 10:34    [564987]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
Не знаю как тут можно ли понять...

SELECT a.id_mainCompany, 

a.id_company,
c.briefName,
c.fullName,
r.id_area, r.name_prntArea, r.scname, r.name_area,
m.dateFix, m.nameDepartment, m.officeName, m.namePost, m.id_employee, m.surname, m.name_, m.patronymic,
a.dateHistory,
c.regNumber,
c.license,
c.typeCompany
FROM @actualTreeCompany a
INNER JOIN PS_Company c ON a.id_company=c.id_company
INNER JOIN dbo.fi_GetAreaWithOnePrnt() r ON c.id_area=r.id_area
LEFT JOIN dbo.fi_GetCompanyStaff(@dateActual) m ON a.id_company=m.id_company
WHERE a.id_prntCompany=0
ORDER BY c.briefName

(1 row(s) affected)

StmtText
       |--Compute Scalar(DEFINE:([Expr1027]=isnull([PS_Area].[name_area], %af_src_str_0)))


|--Nested Loops(Left Outer Join, OUTER REFERENCES:([a].[id_company]))

|--Nested Loops(Left Outer Join, OUTER REFERENCES:([PS_Area].[id_prnt_area]))

| |--Nested Loops(Inner Join, OUTER REFERENCES:([PS_Area].[id_typearea]))

| | |--Nested Loops(Inner Join, OUTER REFERENCES:([c].[id_area]))

| | | |--Sort(ORDER BY:([c].[briefName] ASC))

| | | | |--Nested Loops(Inner Join, OUTER REFERENCES:([a].[id_company]))

| | | | |--Table Scan(OBJECT:(@actualTreeCompany AS [a]), WHERE:([a].[id_prntCompany]=0))

| | | | |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Company].[pck_id_company] AS [c]), SEEK:([c].[id_company]=[a].[id_company]) ORDERED FORWARD)

| | | |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Area].[pck_id_area]), SEEK:([PS_Area].[id_area]=[c].[id_area]) ORDERED FORWARD)

| | |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_TypeArea].[pck_id_typearea]), SEEK:([PS_TypeArea].[id_typearea]=[PS_Area].[id_typearea]) ORDERED FORWARD)

| |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Area].[pck_id_area]), SEEK:([PS_Area].[id_area]=[PS_Area].[id_prnt_area]) ORDERED FORWARD)

|--Compute Scalar(DEFINE:([Expr1025]=isnull([PS_Department].[nameDepartment], %af_src_str_1), [Expr1026]=isnull([PS_CompanyOffice].[officeName], %af_src_str_2)))

|--Nested Loops(Left Outer Join, OUTER REFERENCES:([PS_Department].[id_office]))

|--Nested Loops(Left Outer Join, OUTER REFERENCES:([PS_Staff].[id_department]))

| |--Nested Loops(Inner Join, OUTER REFERENCES:([PS_Career].[id_employee]))

| | |--Nested Loops(Inner Join, OUTER REFERENCES:([PS_Staff].[id_post]))

| | | |--Nested Loops(Inner Join, OUTER REFERENCES:([PS_Career].[id_staff]))

| | | | |--Bookmark Lookup(BOOKMARK:([Bmk1021]), OBJECT:([REINSURANCE].[dbo].[PS_Career]))

| | | | | |--Nested Loops(Inner Join, OUTER REFERENCES:([PS_CompanyStaff].[id_staff]))

| | | | | |--Filter(WHERE:([a].[id_company]=[PS_CompanyStaff].[id_company]))

| | | | | | |--Top(1)

| | | | | | |--Segment

| | | | | | |--Sort(ORDER BY:([PS_CompanyStaff].[id_company] DESC, [PS_CompanyStaff].[dateFix] DESC))

| | | | | | |--Bookmark Lookup(BOOKMARK:([Bmk1011]), OBJECT:([REINSURANCE].[dbo].[PS_CompanyStaff]))

| | | | | | |--Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_CompanyStaff].[ni_dateFix]), SEEK:([PS_CompanyStaff].[dateFix] <= [@dateActual]) ORDERED FORWARD)

| | | | | |--Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Career].[ni_id_staff]), SEEK:([PS_Career].[id_staff]=[PS_CompanyStaff].[id_staff]) ORDERED FORWARD)

| | | | |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Staff].[pck_id_staff]), SEEK:([PS_Staff].[id_staff]=[PS_Career].[id_staff]) ORDERED FORWARD)

| | | |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Post].[pck_id_post]), SEEK:([PS_Post].[id_post]=[PS_Staff].[id_post]) ORDERED FORWARD)

| | |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Employee].[pck_id_employee]), SEEK:([PS_Employee].[id_employee]=[PS_Career].[id_employee]) ORDERED FORWARD)

| |--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_Department].[pck_id_department]), SEEK:([PS_Department].[id_department]=[PS_Staff].[id_department]) ORDERED FORWARD)

|--Clustered Index Seek(OBJECT:([REINSURANCE].[dbo].[PS_CompanyOffice].[pck_id_subsidiary]), SEEK:([PS_CompanyOffice].[id_office]=[PS_Department].[id_office]) ORDERED FORWARD)
5 мар 04, 10:49    [565028]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
Самое интересное, что вчера написав сей запрос он какое-то время отрабатывал быстро, потом стал 15 сек.

попробовал так - не помогло:
SELECT
FROM @actualTreeCompany a
INNER JOIN PS_Company c ON a.id_company=c.id_company AND
a.id_prntCompany=0
INNER JOIN dbo.fi_GetAreaWithOnePrnt() r ON c.id_area=r.id_area
LEFT JOIN dbo.fi_GetCompanyStaff(@dateActual) m ON a.id_company=m.id_company
ORDER BY c.briefName
5 мар 04, 10:59    [565063]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
В @actualTreeCompany много строк?
5 мар 04, 11:05    [565082]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
rst
Member

Откуда: Йобурк
Сообщений: 1005
ну а если слить dbo.fi_GetCompanyStaff(@dateActual) во временную таблицу?
сколько там записей-то кстати?
5 мар 04, 11:05    [565086]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
Разбил на 2 части получил 3 сек :-) Ещё как-то можно ускорить енто дело?


SELECT a.id_mainCompany,
a.id_company,
c.briefName,
c.fullName,
r.id_area, r.name_prntArea, r.scname, r.name_area,
a.dateHistory,
c.regNumber,
c.license,
c.typeCompany
INTO #a
FROM @actualTreeCompany a
INNER JOIN PS_Company c ON a.id_company=c.id_company AND a.id_prntCompany=0
INNER JOIN dbo.fi_GetAreaWithOnePrnt() r ON c.id_area=r.id_area




SELECT a.*, m.dateFix, m.nameDepartment, m.officeName, m.namePost, m.id_employee, m.surname, m.name_, m.patronymic
FROM #a a
LEFT JOIN dbo.fi_GetCompanyStaff(@dateActual) m ON a.id_company=m.id_company
5 мар 04, 11:06    [565093]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Планы давай.
5 мар 04, 11:09    [565099]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
Счас в @actualTreeCompany пока 2000 строк, но может возрасти в 2 раза (чем чёрт не шутит :-)

В данной хранимой процедуре я ещё планирую ввести входные параметры,
которые будут ограничивать выборку (ну там id сотрудника, региона, ..., первая буква в наименовании компании=для пэйджинга)

А пока вот решил по максимуму погонять, поскольку могут попросить сформировать список всех компаний со всеми их атрибутами
5 мар 04, 11:12    [565108]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
А id_company в @actualTreeCompany является PK?
5 мар 04, 11:16    [565118]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Я за тем все эти наводящие вопросы задаю, потому что вижу в плане

|--Table Scan(OBJECT:(@actualTreeCompany AS [a]), WHERE:([a].[id_prntCompany]=0))

что вызвано отсутствием индекса. Но,...
5 мар 04, 11:19    [565128]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
2tpg:

Да, id_company в табличной переменной @actualTreeCompany является PK
5 мар 04, 11:19    [565129]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
да, индекса я не создавал в табличной переменной, а создавая его
не будет ли тормозов при заполнении @actualTreeCompany ?
5 мар 04, 11:21    [565135]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
А что если попробовать заменить табличную переменную на временную таблицу и обложить её индексами. Или сделать хотябы констрэйн UNIQUE на колонки id_company и id_prntCompany.
5 мар 04, 11:24    [565142]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
2tpg :

Добавил PRIMARY KEY на id_company в @actualTreeCompany запрос стал делатца <=1 сек :-)
А табличную переменную посчитал лучше чем временная табличка, т.к. первая насколько я понимаю целиком в памяти держится?

Кстати, счас в SQL2000 как лучше
SELECT ..... INTO #a FROM b
или
CREATE TABLE #a (....)
INSERT #a (....) SELECT .... FROM b

т.е. во втором случае база tempDb меньше напрягается или в SQL2000 это как-то разрешено?
5 мар 04, 11:31    [565156]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
ИМХО, SELECT ..... INTO - проще код писать, CREATE TABLE - более гибко.
5 мар 04, 11:35    [565171]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
табличная переменная как мне кажется выигрывает по скорости!?
5 мар 04, 11:37    [565176]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Не всегда. На временную таблицу можно навесить любой индекс, а на табличную переменную - только констрэнты (если мне не изменяет склероз)...
5 мар 04, 11:39    [565187]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
Sa
Member

Откуда: Ekaterinburg
Сообщений: 4019
>табличная переменная как мне кажется выигрывает по скорости!?
У меня бывает по разному попробуй и так и так.
5 мар 04, 11:39    [565191]     Ответить | Цитировать Сообщить модератору
 Re: Если LEFT JOIN - то тормоза...  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
А вообще в данном запросе у меня стягивается информация из 12 таблиц (не дай бог какую ещё атрибутику затребуют манагеры)....
Значит SQL2000 не всегда может разобрться как ему быть оптимальнее, надо на времянки бить, шоб ему подмочь. До сих пор как-то не сталкивался с тормозами

Ладно, спасиб за помосЧь :-))
5 мар 04, 11:47    [565205]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить