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

Откуда: Мгн
Сообщений: 12
вариант 1 (выполняется за секунду):

create table ##t321(zav_nom varchar(20), ascfrom varchar(20))
insert into ##t321
select zav_nom, ascfrom
from SRV_GOS.unite.dbo.countexp_chk with(nolock)
where loaded_wait is null
group by zav_nom, ascfrom having count(distinct CONVERT(DATETIME, CONVERT(VARCHAR, date_ins, 112))) > 3

select rtrim(ltrim(ac.zav_nom)) zav_nom, rtc.short_name, ac.adr ab_calc_adr, ac.ab_point_adr
from _ab_point ap with(nolock), _ab_calc ac with(nolock), v_rnt_typecalc rtc with(nolock),
##t321 chk
where ac.date_end is null
and ap.date_end is null
and ac.ab_point_adr = ap.adr
and ac.nls_id = ap.nls_id
and isnull(ap.ref1_id, 0) <> 1
and rtc.typecalc_id = ac.typecalc_id
and rtrim(ltrim(rtc.short_name)) = rtrim(ltrim(chk.ascfrom)) collate SQL_Latin1_General_CP1251_CI_AS
and dbo.v_rnt_del_null(ac.zav_nom) = dbo.v_rnt_del_null(chk.zav_nom) collate SQL_Latin1_General_CP1251_CI_AS

drop table ##t321


вариант 2 (выполняется очень долго):

select rtrim(ltrim(ac.zav_nom)) zav_nom, rtc.short_name, ac.adr ab_calc_adr, ac.ab_point_adr
from _ab_point ap with(nolock), _ab_calc ac with(nolock), v_rnt_typecalc rtc with(nolock),
(select zav_nom, ascfrom
from SRV_GOS.unite.dbo.countexp_chk with(nolock)
where loaded_wait is null--rnt, 2011.10.20
group by zav_nom, ascfrom having count(distinct CONVERT(DATETIME, CONVERT(VARCHAR, date_ins, 112))) > 3) chk
where ac.date_end is null
and ap.date_end is null
and ac.ab_point_adr = ap.adr
and ac.nls_id = ap.nls_id
and isnull(ap.ref1_id, 0) <> 1
and rtc.typecalc_id = ac.typecalc_id
and rtrim(ltrim(rtc.short_name)) = rtrim(ltrim(chk.ascfrom))
and dbo.v_rnt_del_null(ac.zav_nom) = dbo.v_rnt_del_null(chk.zav_nom)


где srv_gos - linked server.
Вопрос: почему вариант 2 выполняется долго? утром отрабатывал за секунду. а сейчас виснет. нагрузку юзеров на сервер не учитывать.
20 окт 11, 09:02    [11470202]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с нескольких серверов (linked servers)  [new]
Glory
Member

Откуда:
Сообщений: 104751
rnt777
Вопрос: почему вариант 2 выполняется долго

Потому что
- линкед сервер медленный
- сеть медленная
- данных много
- план неоптимальный
- запрос неоптимальный
- блокироки
- ресурсов не хватает
- ....
20 окт 11, 09:06    [11470219]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с нескольких серверов (linked servers)  [new]
hpv
Member

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

выложите реальные планы 2-х своих вариантов.
20 окт 11, 10:32    [11470642]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с нескольких серверов (linked servers)  [new]
rnt777
Member

Откуда: Мгн
Сообщений: 12
hpv
rnt777,

выложите реальные планы 2-х своих вариантов.


вариант 1:

  |--Merge Join(Inner Join, MERGE:([tc].[typecalc_id])=([rtc].[typecalc_id]), RESIDUAL:([_privat_work].[dbo].[v_rnt_typecalc].[typecalc_id] as [rtc].[typecalc_id]=[_privat_work].[dbo].[typecalc].[typecalc_id] as [tc].[typecalc_id]))
       |--Compute Scalar(DEFINE:([Expr1015]=rtrim(ltrim([_privat_work].[dbo].[typecalc].[name_calc] as [tc].[name_calc]))))
       |    |--Clustered Index Scan(OBJECT:([_privat_work].[dbo].[typecalc].[PK_typecalc] AS [tc]), ORDERED FORWARD)
       |--Filter(WHERE:(isnull([_privat_work].[dbo].[_ab_point].[ref1_id] as [ap].[ref1_id],(0))<>(1) AND [_privat_work].[dbo].[_ab_point].[date_end] as [ap].[date_end] IS NULL))
            |--Nested Loops(Inner Join, OUTER REFERENCES:([ap].[adr]))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([ac].[nls_id], [ac].[ab_point_adr]))
                 |    |--Compute Scalar(DEFINE:([Expr1013]=rtrim(ltrim([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom]))))
                 |    |    |--Filter(WHERE:([_privat_work].[dbo].[_ab_calc].[date_end] as [ac].[date_end] IS NULL))
                 |    |         |--Nested Loops(Inner Join, OUTER REFERENCES:([ac].[adr]))
                 |    |              |--Nested Loops(Inner Join, OUTER REFERENCES:([rtc].[typecalc_id], [SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom]))
                 |    |              |    |--Nested Loops(Inner Join, WHERE:([Expr1016]=rtrim(ltrim([SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]))))
                 |    |              |    |    |--Compute Scalar(DEFINE:([Expr1014]=rtrim(ltrim([_privat_work].[dbo].[v_rnt_typecalc].[short_name] as [rtc].[short_name])), [Expr1016]=CONVERT_IMPLICIT(nvarchar(20),rtrim(ltrim([_privat_work].[dbo].[v_rnt_typecalc].[short_name] as [rtc].[short_name])),0)))
                 |    |              |    |    |    |--Sort(ORDER BY:([rtc].[typecalc_id] ASC))
                 |    |              |    |    |         |--Table Scan(OBJECT:([_privat_work].[dbo].[v_rnt_typecalc] AS [rtc]))
                 |    |              |    |    |--Table Spool
                 |    |              |    |         |--Compute Scalar(DEFINE:([SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom], [SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]))
                 |    |              |    |              |--Remote Query(SOURCE:(SRV_GOS), QUERY:(SELECT "Col1023","Col1026" FROM (SELECT "Tbl1011"."zav_nom" "Col1023","Tbl1011"."ascfrom" "Col1026",COUNT(DISTINCT CONVERT(datetime,CONVERT(varchar(30),"Tbl1011"."date_ins",112),0)) "Expr1012" FROM "unite"."dbo"."countexp_chk" "Tbl1011" WHERE "Tbl1011"."loaded_wait" IS NULL GROUP BY "Tbl1011"."zav_nom","Tbl1011"."ascfrom") Qry1029 WHERE "Expr1012">(3)))
                 |    |              |    |--Filter(WHERE:([_privat_work].[dbo].[v_rnt_del_null]([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom])=[_privat_work].[dbo].[v_rnt_del_null](CONVERT_IMPLICIT(varchar(200),[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom],0))))
                 |    |              |         |--Index Seek(OBJECT:([_privat_work].[dbo].[_ab_calc].[typecalc] AS [ac]), SEEK:([ac].[typecalc_id]=[_privat_work].[dbo].[v_rnt_typecalc].[typecalc_id] as [rtc].[typecalc_id]) ORDERED FORWARD)
                 |    |              |--Clustered Index Seek(OBJECT:([_privat_work].[dbo].[_ab_calc].[PK__ab_calc] AS [ac]), SEEK:([ac].[adr]=[_privat_work].[dbo].[_ab_calc].[adr] as [ac].[adr]) LOOKUP ORDERED FORWARD)
                 |    |--Index Seek(OBJECT:([_privat_work].[dbo].[_ab_point].[nls_service] AS [ap]), SEEK:([ap].[nls_id]=[_privat_work].[dbo].[_ab_calc].[nls_id] as [ac].[nls_id]),  WHERE:([_privat_work].[dbo].[_ab_calc].[ab_point_adr] as [ac].[ab_point_adr]=[_privat_work].[dbo].[_ab_point].[adr] as [ap].[adr]) ORDERED FORWARD)
                 |--Clustered Index Seek(OBJECT:([_privat_work].[dbo].[_ab_point].[PK__ab_point] AS [ap]), SEEK:([ap].[adr]=[_privat_work].[dbo].[_ab_point].[adr] as [ap].[adr]) LOOKUP ORDERED FORWARD)


вариант 2:

insert:

insert into ##t321  select zav_nom, ascfrom  from SRV_GOS.unite.dbo.countexp_chk with(nolock)  where loaded_wait is null  group by zav_nom, ascfrom having count(distinct CONVERT(DATETIME, CONVERT(VARCHAR, date_ins, 112))) > 3
  |--Table Insert(OBJECT:([tempdb].[dbo].[##t321]), SET:([tempdb].[dbo].[##t321].[zav_nom] = [Expr1008],[tempdb].[dbo].[##t321].[ascfrom] = [Expr1009]))
       |--Table Spool
            |--Compute Scalar(DEFINE:([Expr1008]=CONVERT_IMPLICIT(varchar(20),[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom],0), [Expr1009]=CONVERT_IMPLICIT(varchar(20),[SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom],0)))
                 |--Top(ROWCOUNT est 0)
                      |--Compute Scalar(DEFINE:([SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom], [SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]))
                           |--Remote Query(SOURCE:(SRV_GOS), QUERY:(SELECT "Col1021","Col1024" FROM (SELECT "Tbl1006"."zav_nom" "Col1021","Tbl1006"."ascfrom" "Col1024",COUNT(DISTINCT CONVERT(datetime,CONVERT(varchar(30),"Tbl1006"."date_ins",112),0)) "Expr1007" FROM "unite"."dbo"."countexp_chk" "Tbl1006" WITH (NOLOCK) WHERE "Tbl1006"."loaded_wait" IS NULL GROUP BY "Tbl1006"."zav_nom","Tbl1006"."ascfrom") Qry1027 WHERE "Expr1007">(3)))


select:
select rtrim(ltrim(ac.zav_nom)) zav_nom, rtc.short_name, ac.adr ab_calc_adr, ac.ab_point_adr        from _ab_point ap with(nolock), _ab_calc ac with(nolock), v_rnt_typecalc rtc with(nolock),             ##t321 chk        where ac.date_end is null        and ap.date_end is null        and ac.ab_point_adr = ap.adr        and ac.nls_id = ap.nls_id        and isnull(ap.ref1_id, 0) <> 1        and rtc.typecalc_id = ac.typecalc_id        and rtrim(ltrim(rtc.short_name)) = rtrim(ltrim(chk.ascfrom)) collate SQL_Latin1_General_CP1251_CI_AS        and dbo.v_rnt_del_null(ac.zav_nom) = dbo.v_rnt_del_null(chk.zav_nom) collate SQL_Latin1_General_CP1251_CI_AS
  |--Hash Match(Inner Join, HASH:([Expr1012], [Expr1014])=([Expr1011], [Expr1015]), RESIDUAL:([Expr1011]=[Expr1012] AND [Expr1015]=[Expr1014]))
       |--Compute Scalar(DEFINE:([Expr1014]=[_privat_work].[dbo].[v_rnt_del_null]([tempdb].[dbo].[##t321].[zav_nom] as [chk].[zav_nom])))
       |    |--Compute Scalar(DEFINE:([Expr1012]=CONVERT(varchar(20),rtrim(ltrim([tempdb].[dbo].[##t321].[ascfrom] as [chk].[ascfrom])),0)))
       |         |--Table Scan(OBJECT:([tempdb].[dbo].[##t321] AS [chk]))
       |--Compute Scalar(DEFINE:([Expr1015]=[_privat_work].[dbo].[v_rnt_del_null]([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom])))
            |--Merge Join(Inner Join, MERGE:([ap].[adr], [ap].[nls_id])=([ac].[ab_point_adr], [ac].[nls_id]), RESIDUAL:([_privat_work].[dbo].[_ab_calc].[ab_point_adr] as [ac].[ab_point_adr]=[_privat_work].[dbo].[_ab_point].[adr] as [ap].[adr] AND [_privat_work].[dbo].[_ab_calc].[nls_id] as [ac].[nls_id]=[_privat_work].[dbo].[_ab_point].[nls_id] as [ap].[nls_id]))
                 |--Clustered Index Scan(OBJECT:([_privat_work].[dbo].[_ab_point].[PK__ab_point] AS [ap]),  WHERE:([_privat_work].[dbo].[_ab_point].[date_end] as [ap].[date_end] IS NULL AND isnull([_privat_work].[dbo].[_ab_point].[ref1_id] as [ap].[ref1_id],(0))<>(1)) ORDERED FORWARD)
                 |--Sort(ORDER BY:([ac].[ab_point_adr] ASC, [ac].[nls_id] ASC))
                      |--Hash Match(Inner Join, HASH:([rtc].[typecalc_id])=([ac].[typecalc_id]), RESIDUAL:([_privat_work].[dbo].[v_rnt_typecalc].[typecalc_id] as [rtc].[typecalc_id]=[_privat_work].[dbo].[_ab_calc].[typecalc_id] as [ac].[typecalc_id]))
                           |--Compute Scalar(DEFINE:([Expr1011]=rtrim(ltrim([_privat_work].[dbo].[v_rnt_typecalc].[short_name] as [rtc].[short_name]))))
                           |    |--Table Scan(OBJECT:([_privat_work].[dbo].[v_rnt_typecalc] AS [rtc]))
                           |--Compute Scalar(DEFINE:([Expr1010]=rtrim(ltrim([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom]))))
                                |--Clustered Index Scan(OBJECT:([_privat_work].[dbo].[_ab_calc].[PK__ab_calc] AS [ac]), WHERE:([_privat_work].[dbo].[_ab_calc].[date_end] as [ac].[date_end] IS NULL))
20 окт 11, 11:01    [11470886]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с нескольких серверов (linked servers)  [new]
hpv
Member

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

Это планы, не для запросов из 1-го сообщения, перепроверьте плиз.

И оформите планы в тэге spoiler.
20 окт 11, 11:08    [11470959]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с нескольких серверов (linked servers)  [new]
rnt777
Member

Откуда: Мгн
Сообщений: 12
перепутал местами.

Вариант 1 (действительный план):

Insert


+

insert into ##t321  select zav_nom, ascfrom  from SRV_GOS.unite.dbo.countexp_chk with(nolock)  where loaded_wait is null  group by zav_nom, ascfrom having count(distinct CONVERT(DATETIME, CONVERT(VARCHAR, date_ins, 112))) > 3
  |--Table Insert(OBJECT:([tempdb].[dbo].[##t321]), SET:([tempdb].[dbo].[##t321].[zav_nom] = [Expr1008],[tempdb].[dbo].[##t321].[ascfrom] = [Expr1009]))
       |--Table Spool
            |--Compute Scalar(DEFINE:([Expr1008]=CONVERT_IMPLICIT(varchar(20),[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom],0), [Expr1009]=CONVERT_IMPLICIT(varchar(20),[SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom],0)))
                 |--Top(ROWCOUNT est 0)
                      |--Compute Scalar(DEFINE:([SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom], [SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]))
                           |--Remote Query(SOURCE:(SRV_GOS), QUERY:(SELECT "Col1021","Col1024" FROM (SELECT "Tbl1006"."zav_nom" "Col1021","Tbl1006"."ascfrom" "Col1024",COUNT(DISTINCT CONVERT(datetime,CONVERT(varchar(30),"Tbl1006"."date_ins",112),0)) "Expr1007" FROM "unite"."dbo"."countexp_chk" "Tbl1006" WITH (NOLOCK) WHERE "Tbl1006"."loaded_wait" IS NULL GROUP BY "Tbl1006"."zav_nom","Tbl1006"."ascfrom") Qry1027 WHERE "Expr1007">(3)))



Select

+

select rtrim(ltrim(ac.zav_nom)) zav_nom, rtc.short_name, ac.adr ab_calc_adr, ac.ab_point_adr        from _ab_point ap with(nolock), _ab_calc ac with(nolock), v_rnt_typecalc rtc with(nolock),             ##t321 chk        where ac.date_end is null        and ap.date_end is null        and ac.ab_point_adr = ap.adr        and ac.nls_id = ap.nls_id        and isnull(ap.ref1_id, 0) <> 1        and rtc.typecalc_id = ac.typecalc_id        and rtrim(ltrim(rtc.short_name)) = rtrim(ltrim(chk.ascfrom)) collate SQL_Latin1_General_CP1251_CI_AS        and dbo.v_rnt_del_null(ac.zav_nom) = dbo.v_rnt_del_null(chk.zav_nom) collate SQL_Latin1_General_CP1251_CI_AS
  |--Hash Match(Inner Join, HASH:([Expr1012], [Expr1014])=([Expr1011], [Expr1015]), RESIDUAL:([Expr1011]=[Expr1012] AND [Expr1015]=[Expr1014]))
       |--Compute Scalar(DEFINE:([Expr1014]=[_privat_work].[dbo].[v_rnt_del_null]([tempdb].[dbo].[##t321].[zav_nom] as [chk].[zav_nom])))
       |    |--Compute Scalar(DEFINE:([Expr1012]=CONVERT(varchar(20),rtrim(ltrim([tempdb].[dbo].[##t321].[ascfrom] as [chk].[ascfrom])),0)))
       |         |--Table Scan(OBJECT:([tempdb].[dbo].[##t321] AS [chk]))
       |--Compute Scalar(DEFINE:([Expr1015]=[_privat_work].[dbo].[v_rnt_del_null]([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom])))
            |--Merge Join(Inner Join, MERGE:([ap].[adr], [ap].[nls_id])=([ac].[ab_point_adr], [ac].[nls_id]), RESIDUAL:([_privat_work].[dbo].[_ab_calc].[ab_point_adr] as [ac].[ab_point_adr]=[_privat_work].[dbo].[_ab_point].[adr] as [ap].[adr] AND [_privat_work].[dbo].[_ab_calc].[nls_id] as [ac].[nls_id]=[_privat_work].[dbo].[_ab_point].[nls_id] as [ap].[nls_id]))
                 |--Clustered Index Scan(OBJECT:([_privat_work].[dbo].[_ab_point].[PK__ab_point] AS [ap]),  WHERE:([_privat_work].[dbo].[_ab_point].[date_end] as [ap].[date_end] IS NULL AND isnull([_privat_work].[dbo].[_ab_point].[ref1_id] as [ap].[ref1_id],(0))<>(1)) ORDERED FORWARD)
                 |--Sort(ORDER BY:([ac].[ab_point_adr] ASC, [ac].[nls_id] ASC))
                      |--Hash Match(Inner Join, HASH:([rtc].[typecalc_id])=([ac].[typecalc_id]), RESIDUAL:([_privat_work].[dbo].[v_rnt_typecalc].[typecalc_id] as [rtc].[typecalc_id]=[_privat_work].[dbo].[_ab_calc].[typecalc_id] as [ac].[typecalc_id]))
                           |--Compute Scalar(DEFINE:([Expr1011]=rtrim(ltrim([_privat_work].[dbo].[v_rnt_typecalc].[short_name] as [rtc].[short_name]))))
                           |    |--Table Scan(OBJECT:([_privat_work].[dbo].[v_rnt_typecalc] AS [rtc]))
                           |--Compute Scalar(DEFINE:([Expr1010]=rtrim(ltrim([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom]))))
                                |--Clustered Index Scan(OBJECT:([_privat_work].[dbo].[_ab_calc].[PK__ab_calc] AS [ac]), WHERE:([_privat_work].[dbo].[_ab_calc].[date_end] as [ac].[date_end] IS NULL))



Вариант 2 (предварительный план):

+

  select rtrim(ltrim(ac.zav_nom)) zav_nom, rtrim(ltrim(rtc.short_name)) short_name, ac.adr ab_calc_adr, ac.ab_point_adr, rtrim(ltrim(tc.name_calc)) name_calc        from _ab_point ap, _ab_calc ac, v_rnt_typecalc rtc, typecalc tc,             (select zav_nom, ascfrom              from SRV_GOS.unite.dbo.countexp_chk              where loaded_wait is null              group by zav_nom, ascfrom having count(distinct CONVERT(DATETIME, CONVERT(VARCHAR, date_ins, 112))) > 3) chk        where ac.date_end is null        and ap.date_end is null        and ac.ab_point_adr = ap.adr        and ac.nls_id = ap.nls_id        and isnull(ap.ref1_id, 0) <> 1        and rtc.typecalc_id = ac.typecalc_id        and rtc.typecalc_id = tc.typecalc_id        and rtrim(ltrim(rtc.short_name)) = rtrim(ltrim(chk.ascfrom)) collate SQL_Latin1_General_CP1251_CI_AS        and dbo.v_rnt_del_null(ac.zav_nom) = dbo.v_rnt_del_null(chk.zav_nom) collate SQL_Latin1_General_CP1251_CI_AS
  |--Merge Join(Inner Join, MERGE:([tc].[typecalc_id])=([rtc].[typecalc_id]), RESIDUAL:([_privat_work].[dbo].[v_rnt_typecalc].[typecalc_id] as [rtc].[typecalc_id]=[_privat_work].[dbo].[typecalc].[typecalc_id] as [tc].[typecalc_id]))
       |--Compute Scalar(DEFINE:([Expr1015]=rtrim(ltrim([_privat_work].[dbo].[typecalc].[name_calc] as [tc].[name_calc]))))
       |    |--Clustered Index Scan(OBJECT:([_privat_work].[dbo].[typecalc].[PK_typecalc] AS [tc]), ORDERED FORWARD)
       |--Filter(WHERE:(isnull([_privat_work].[dbo].[_ab_point].[ref1_id] as [ap].[ref1_id],(0))<>(1) AND [_privat_work].[dbo].[_ab_point].[date_end] as [ap].[date_end] IS NULL))
            |--Nested Loops(Inner Join, OUTER REFERENCES:([ap].[adr]))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([ac].[nls_id], [ac].[ab_point_adr]))
                 |    |--Compute Scalar(DEFINE:([Expr1013]=rtrim(ltrim([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom]))))
                 |    |    |--Filter(WHERE:([_privat_work].[dbo].[_ab_calc].[date_end] as [ac].[date_end] IS NULL))
                 |    |         |--Nested Loops(Inner Join, OUTER REFERENCES:([ac].[adr]))
                 |    |              |--Nested Loops(Inner Join, OUTER REFERENCES:([rtc].[typecalc_id], [SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom]))
                 |    |              |    |--Nested Loops(Inner Join, WHERE:([Expr1016]=rtrim(ltrim([SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]))))
                 |    |              |    |    |--Compute Scalar(DEFINE:([Expr1014]=rtrim(ltrim([_privat_work].[dbo].[v_rnt_typecalc].[short_name] as [rtc].[short_name])), [Expr1016]=CONVERT_IMPLICIT(nvarchar(20),rtrim(ltrim([_privat_work].[dbo].[v_rnt_typecalc].[short_name] as [rtc].[short_name])),0)))
                 |    |              |    |    |    |--Sort(ORDER BY:([rtc].[typecalc_id] ASC))
                 |    |              |    |    |         |--Table Scan(OBJECT:([_privat_work].[dbo].[v_rnt_typecalc] AS [rtc]))
                 |    |              |    |    |--Table Spool
                 |    |              |    |         |--Compute Scalar(DEFINE:([SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom], [SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]=[SRV_GOS].[unite].[dbo].[countexp_chk].[ascfrom]))
                 |    |              |    |              |--Remote Query(SOURCE:(SRV_GOS), QUERY:(SELECT "Col1023","Col1026" FROM (SELECT "Tbl1011"."zav_nom" "Col1023","Tbl1011"."ascfrom" "Col1026",COUNT(DISTINCT CONVERT(datetime,CONVERT(varchar(30),"Tbl1011"."date_ins",112),0)) "Expr1012" FROM "unite"."dbo"."countexp_chk" "Tbl1011" WHERE "Tbl1011"."loaded_wait" IS NULL GROUP BY "Tbl1011"."zav_nom","Tbl1011"."ascfrom") Qry1029 WHERE "Expr1012">(3)))
                 |    |              |    |--Filter(WHERE:([_privat_work].[dbo].[v_rnt_del_null]([_privat_work].[dbo].[_ab_calc].[zav_nom] as [ac].[zav_nom])=[_privat_work].[dbo].[v_rnt_del_null](CONVERT_IMPLICIT(varchar(200),[SRV_GOS].[unite].[dbo].[countexp_chk].[zav_nom],0))))
                 |    |              |         |--Index Seek(OBJECT:([_privat_work].[dbo].[_ab_calc].[typecalc] AS [ac]), SEEK:([ac].[typecalc_id]=[_privat_work].[dbo].[v_rnt_typecalc].[typecalc_id] as [rtc].[typecalc_id]) ORDERED FORWARD)
                 |    |              |--Clustered Index Seek(OBJECT:([_privat_work].[dbo].[_ab_calc].[PK__ab_calc] AS [ac]), SEEK:([ac].[adr]=[_privat_work].[dbo].[_ab_calc].[adr] as [ac].[adr]) LOOKUP ORDERED FORWARD)
                 |    |--Index Seek(OBJECT:([_privat_work].[dbo].[_ab_point].[nls_service] AS [ap]), SEEK:([ap].[nls_id]=[_privat_work].[dbo].[_ab_calc].[nls_id] as [ac].[nls_id]),  WHERE:([_privat_work].[dbo].[_ab_calc].[ab_point_adr] as [ac].[ab_point_adr]=[_privat_work].[dbo].[_ab_point].[adr] as [ap].[adr]) ORDERED FORWARD)
                 |--Clustered Index Seek(OBJECT:([_privat_work].[dbo].[_ab_point].[PK__ab_point] AS [ap]), SEEK:([ap].[adr]=[_privat_work].[dbo].[_ab_point].[adr] as [ap].[adr]) LOOKUP ORDERED FORWARD)


Сообщение было отредактировано: 20 окт 11, 18:18
20 окт 11, 11:20    [11471074]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с нескольких серверов (linked servers)  [new]
МуМу
Member

Откуда:
Сообщений: 1134
Попробуйте сделать пересчет статистики с full scan по всем таблицам. Выполните их заново.(возможно они изменятся)
Скорее всего по основным полям объединения нет индексов. Поэтому оптимизатор берет в одном случае и идет вложенными циклами а в другом случая хеш джоином. Вложенными циклами если будет перемножение хотя бы 1000 на 1000 и на 1000 будет весьма долго. Хеш джоин сделает это значительно быстрее.

Как от этого избавится - добавить правильные индексы, регулярнее персчитывать статистку. Просто пересчет статистики возможно избавит но не так надежно будет. Использование временной таблицы делает запрос боблее предсказуемым и надежным потому как сервер понимает размер выборки.
20 окт 11, 14:22    [11472745]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с нескольких серверов (linked servers)  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
rnt777,

А у пользователя есть права на то чтобы посмотреть статистику на linked server? Если нет, то о количестве строк в SRV_GOS.unite.dbo.countexp_chk сервер может только догадываться, отсюда и кривые планы. Так что лучже уж через времянку.

http://msdn.microsoft.com/ru-ru/library/ms175129.aspx
Чтобы создать наиболее эффективный план запроса при использовании таблицы на связанном сервере, обработчик запросов должен иметь статистику распределения данных со связанного сервера. Пользователи, имеющие ограниченные разрешения для работы со столбцами таблицы, могут не иметь возможности получить необходимую статистику и, как следствие, получат менее эффективный план запроса. Если связанный сервер является экземпляром SQL Server, для получения всей доступной статистики пользователь должен быть владельцем таблицы или членом предопределенной роли сервера sysadmin, db_owner или предопределенной роли базы данных db_ddladmin на связанном сервере.
20 окт 11, 22:13    [11475676]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить