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

Откуда:
Сообщений: 625
Есть table1 и подчиненная table2 (1 ко многим). Связка по полю t_id
Нужно вытащить записи из первой и самую последнюю запись из table2 по полю DT (datetime)
select  t1.f1,
          t1.f2,
          (select top 1 t2.f1 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f1,
          (select top 1 t2.f2 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f2,
          (select top 1 t2.f3 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f3,
          (select top 1 t2.f4 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f4
from table1 t1

Все работает, но для каждого из последних 4 полей приходится 4 раза сканить table2. Как оптимизированее сделать. Думаю когда записей будут миллионы, то будет тормозить
27 сен 12, 13:33    [13231738]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация запроса  [new]
invm
Member

Откуда: Москва
Сообщений: 9823
select
 t1.f1,
 t1.f2, t.f1, t.f2, t.f3, t.f4
from
 table1 t1 outer apply
 (select top (1) f1, f2, f3, f4 from table2 where t_id = t1.t_id order by DT desc) t;
27 сен 12, 13:48    [13231931]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация запроса  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
abort
Есть table1 и подчиненная table2 (1 ко многим). Связка по полю t_id
Нужно вытащить записи из первой и самую последнюю запись из table2 по полю DT (datetime)
select  t1.f1,
          t1.f2,
          (select top 1 t2.f1 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f1,
          (select top 1 t2.f2 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f2,
          (select top 1 t2.f3 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f3,
          (select top 1 t2.f4 from table2 t2 where t1.t_id = t2.t_id order by t2.DT desc) as t2_f4
from table1 t1

Все работает, но для каждого из последних 4 полей приходится 4 раза сканить table2. Как оптимизированее сделать. Думаю когда записей будут миллионы, то будет тормозить
Зависит от версии, конечно.
Но способов - несколько десятков. Например:
select
 t1_f1=t1.f1,
 t1_f2=t1.f2,
 t2_f1=t2.f1,
 t2_f2=t2.f2,
 t2_f3=t2.f3,
 t2_f4=t2.f4
from table1 t1
outer apply (select top(1) t2.f1,t2.f2,t2.f3,t2.f4 from table2 t2 where t2.t_id = t1.t_id order by t2.DT desc) t2
27 сен 12, 13:50    [13231953]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация запроса  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Эх, опоздал...
Ну, тогда
select
 t1_f1=t1.f1,
 t1_f2=t1.f2,
 t2_f1=t2.f1,
 t2_f2=t2.f2,
 t2_f3=t2.f3,
 t2_f4=t2.f4
from table1 t1
left join (select n=row_number()over(partition by t_id order by DT desc),* from table2) t2 on t1.t_id = t2.t_id and t2.n=1;
27 сен 12, 13:56    [13232034]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация запроса  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
Эх, опоздал...
Ну, тогда
select
 t1_f1=t1.f1,
 t1_f2=t1.f2,
 t2_f1=t2.f1,
 t2_f2=t2.f2,
 t2_f3=t2.f3,
 t2_f4=t2.f4
from table1 t1
left join (select n=row_number()over(partition by t_id order by DT desc),* from table2) t2 on t1.t_id = t2.t_id and t2.n=1;
Наверно, и так можно:
select
 t1_f1=t1.f1,
 t1_f2=t1.f2,
 t2_f1=t2.f1,
 t2_f2=t2.f2,
 t2_f3=t2.f3,
 t2_f4=t2.f4
from table1 t1
left join (select top(1) with ties n=row_number()over(partition by t_id order by DT desc),* from table2 order by n) t2 on t1.t_id = t2.t_id;
27 сен 12, 13:58    [13232065]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация запроса  [new]
abort
Member

Откуда:
Сообщений: 625
спасибо за помощь
28 сен 12, 13:14    [13238315]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить