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

Откуда: Империя Добра
Сообщений: 37010
хотелось бы сделать запрос более оптимальным
create table #t(ID int, NUM1 int ,NUM2 int,INSDATE date)
insert #t(ID, NUM1,NUM2,INSDATE) values
(1,1,3,'2001-01-01'),
(1,2,2,'2001-01-02'),
(1,3,1,'2001-01-03'),
(2,1,3,'2001-01-04'),
(2,2,2,'2001-01-05'),
(2,3,1,'2001-01-06')

select ID,  
(select INSDATE from #t t2 where t1.ID = t2.ID and t2.NUM1 = 1),
(select INSDATE from #t t2 where t1.ID = t2.ID and t2.NUM2 = 1)
from #t t1 group by ID
--1, '2001-01-01', '2001-01-03'
--2, '2001-01-04', '2001-01-06'
drop table #t
14 авг 13, 14:25    [14708015]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
iap
Member

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

для начала он должен быть синтаксически правильным.
А для чего продублирован коррелированный подзапрос?
14 авг 13, 14:33    [14708092]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Cammomile
Member

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

Что вы хотите получить от запроса? Что вас не устраивает в том, что вы написали?
14 авг 13, 14:36    [14708106]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Wizandr
Member

Откуда: Империя Добра
Сообщений: 37010
iap
Wizandr,
для начала он должен быть синтаксически правильным.
А для чего продублирован коррелированный подзапрос?


у меня сейчас отрабатывает без синтаксических ошибок
как раз хочу избавиться от второго подзапроса
думаю в сторону CASE
14 авг 13, 14:39    [14708114]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
select 
ID
,max(case when t1.Num1 =1 then INSDATE else null end)
,max(case when t1.Num2=1 then   INSDATE else null end)

from #t t1 group by ID
14 авг 13, 14:39    [14708117]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Wizandr
Member

Откуда: Империя Добра
Сообщений: 37010
Cammomile
Чтобы сделать что-то оптимальным, надо понимать, какой результат вы считаете оптимальным.

Что вы хотите получить от запроса? Что вас не устраивает в том, что вы написали?


хотелось бы уменьшить количество обращений к таблице
14 авг 13, 14:41    [14708126]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Cammomile
Что не устраивает в том, что ТС написал?
коррелированный подзапрос и то что он может вернуть более одного значения.

,Max(CASE WHEN t1.NUM1 = 1 THEN t1.INSDATE END)
,Max(CASE WHEN t1.NUM2 = 1 THEN t1.INSDATE END)
14 авг 13, 14:41    [14708127]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Wizandr
iap
Wizandr,
для начала он должен быть синтаксически правильным.
А для чего продублирован коррелированный подзапрос?


у меня сейчас отрабатывает без синтаксических ошибок
как раз хочу избавиться от второго подзапроса
думаю в сторону CASE
Ступил я... :((
14 авг 13, 14:42    [14708130]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
fwefef
Guest
Wizandr
хотелось бы сделать запрос более оптимальным
create table #t(ID int, NUM1 int ,NUM2 int,INSDATE date)
insert #t(ID, NUM1,NUM2,INSDATE) values
(1,1,3,'2001-01-01'),
(1,2,2,'2001-01-02'),
(1,3,1,'2001-01-03'),
(2,1,3,'2001-01-04'),
(2,2,2,'2001-01-05'),
(2,3,1,'2001-01-06')

select ID,  
(select INSDATE from #t t2 where t1.ID = t2.ID and t2.NUM1 = 1),
(select INSDATE from #t t2 where t1.ID = t2.ID and t2.NUM2 = 1)
from #t t1 group by ID
--1, '2001-01-01', '2001-01-03'
--2, '2001-01-04', '2001-01-06'
drop table #t


select
	id,
	first_value(insdate) over(partition by id order by num1),
	last_value(insdate) over(partition by id order by num1)
from #t t1

create index idx_zzz on #t(id, num1);


если данные именно в такой закономерности как ты привел.
14 авг 13, 14:43    [14708137]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
fewfwefe
Guest
fwefef,

create index idx_zzz on #t(id, num1) include(insdate);
14 авг 13, 14:45    [14708146]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Wizandr
create table #t(ID int, NUM1 int ,NUM2 int,INSDATE date)
insert #t(ID, NUM1,NUM2,INSDATE) values
(1,1,3,'2001-01-01'),
(1,2,2,'2001-01-02'),
(1,3,1,'2001-01-03'),
(2,1,3,'2001-01-04'),
(2,2,2,'2001-01-05'),
(2,3,1,'2001-01-06')
А ещё мне не нравится что NUM1 и NUM2 вместе. Хотя смысл непонятен, но такая структуру с таким запросом плохо коррелируют в понятиях.
Там 2 ключа? {ID,NUM1} и {ID,NUM2}
Запрос можно и написать по другому (без группировки).
14 авг 13, 14:47    [14708153]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
fwefef, вы решаете какую-то другую задачу. Не находите?
14 авг 13, 14:48    [14708161]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Empirical
Member

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

with tab as (
     select ID, 'num1' as typ, INSDATE from #t where num1 = 1 
     union all
     select ID, 'num2' as typ, INSDATE from #t where num2 = 1)

select id, [num1], [num2] from tab as t
pivot (max(insdate) for typ in ([num1],[num2]) ) as p
14 авг 13, 14:49    [14708169]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Wizandr
Member

Откуда: Империя Добра
Сообщений: 37010
Mnior
Wizandr
create table #t(ID int, NUM1 int ,NUM2 int,INSDATE date)
insert #t(ID, NUM1,NUM2,INSDATE) values
(1,1,3,'2001-01-01'),
(1,2,2,'2001-01-02'),
(1,3,1,'2001-01-03'),
(2,1,3,'2001-01-04'),
(2,2,2,'2001-01-05'),
(2,3,1,'2001-01-06')
А ещё мне не нравится что NUM1 и NUM2 вместе. Хотя смысл непонятен, но такая структуру с таким запросом плохо коррелируют в понятиях.
Там 2 ключа? {ID,NUM1} и {ID,NUM2}
Запрос можно и написать по другому (без группировки).


NUM1 и NUM2 - это ранжирование по разным признакам, нужно вывести ID и даты с рангами 1
14 авг 13, 14:56    [14708208]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
frfrfrf
Guest
Mnior
fwefef, вы решаете какую-то другую задачу. Не находите?


нахожу

with m as
(
	select
		id,
		first_value(insdate) over(partition by id order by num1 rows between unbounded preceding and unbounded following) as d1,
		last_value(insdate) over(partition by id order by num1 rows between unbounded preceding and unbounded following) as d2,
		row_number() over(partition by id order by num1) as rn 
	from #t t1
)
select *
from m
where rn = 1;


жаль table spool все портит.
14 авг 13, 14:56    [14708209]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Empirical
Member

Откуда:
Сообщений: 99
Empirical
Wizandr,

with tab as (
     select ID, 'num1' as typ, INSDATE from #t where num1 = 1 
     union all
     select ID, 'num2' as typ, INSDATE from #t where num2 = 1)

select id, [num1], [num2] from tab as t
pivot (max(insdate) for typ in ([num1],[num2]) ) as p


добавила кластерный индекс на id. План до и после добавления индекса
Картинка с другого сайта.
14 авг 13, 14:57    [14708220]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Empirical
Member

Откуда:
Сообщений: 99
Empirical
pivot 


Статистика до и после добавления индекса:

SQL Server Execution Times: CPU time = 0 ms, elapsed time = 48 ms.
SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms.

--------------
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 21 ms.
SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms.
14 авг 13, 15:00    [14708235]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Wizandr
Member

Откуда: Империя Добра
Сообщений: 37010
Мистер Хенки
select 
ID
,max(case when t1.Num1 =1 then INSDATE else null end)
,max(case when t1.Num2=1 then   INSDATE else null end)

from #t t1 group by ID


Спасибо!
14 авг 13, 15:02    [14708245]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Empirical, если использовать обычную группировку с case, будет только одно сканирование таблицы вместо двух при select union all select
14 авг 13, 15:04    [14708258]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Empirical
Member

Откуда:
Сообщений: 99
Мистер Хенки
Empirical, если использовать обычную группировку с case, будет только одно сканирование таблицы вместо двух при select union all select


Согласна, к кейсам надо привыкнуть просто:
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 34 ms.
SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms.

Картинка с другого сайта.
14 авг 13, 15:44    [14708563]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Empirical
Member

Откуда:
Сообщений: 99
Empirical
Мистер Хенки
Empirical, если использовать обычную группировку с case, будет только одно сканирование таблицы вместо двух при select union all select


точнее, так будет планчик
Картинка с другого сайта.
14 авг 13, 15:56    [14708653]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Empirical
Member

Откуда:
Сообщений: 99
[quot Empirical]
Empirical
пропущено...


точнее, так будет планчик при индексе

create clustered index ind_t on #t (id, num1, num2, insdate)
14 авг 13, 15:58    [14708673]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Wizandr
NUM1 и NUM2 - это ранжирование по разным признакам, нужно вывести ID и даты с рангами 1
Проблема в том что в таблице их комбинации, а запрашивается независимо.
Поэтому и спрашивается, или ранжирование независимо - тогда таблицу надо разрезать, или почему спрашивается независимо.

Ибо вполне может быть:
IDNUM1NUM2Data
1112001-01-01
1122001-01-02
1132001-01-03
1212001-01-04
1222001-01-05
1232001-01-06
1312001-01-07
1322001-01-08
1332001-01-09
И какую дату брать из 3х?
И почему Max, а не Min?

Хотя проблема, в понятии "ранжирование".

Ладно, вам это не интересно.
14 авг 13, 17:12    [14709127]     Ответить | Цитировать Сообщить модератору
 Re: как оптимизировать запрос?  [new]
transpose
Member

Откуда:
Сообщений: 188
может еще
where NUM1 = 1 or NUM2 = 1
добавить?
14 авг 13, 17:25    [14709217]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить