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

Откуда:
Сообщений: 283
Добрый день! Прошу поделиться идеями, как можно оптимизировать данный запрос. Его функцией является соединение 2-х таблиц по DEAL_RK и получение исторически упорядоченной версионности с и по (EFFECTIVE_FROM_DT, EFFECTIVE_TO_DT). В каждой из входных таблиц данные лежат с правильной версионностью

select case when taba.DEAL_RK is null then tabb.DEAL_RK else taba.DEAL_RK end as DEAL_RK,
	case when tabb.EFFECTIVE_FROM_DT is null
 	or taba.EFFECTIVE_FROM_DT > tabb.EFFECTIVE_FROM_DT
	then taba.EFFECTIVE_FROM_DT
	else tabb.EFFECTIVE_FROM_DT
	end as EFFECTIVE_FROM_DT,

	case when tabb.EFFECTIVE_TO_DT is null
	or taba.EFFECTIVE_TO_DT < tabb.EFFECTIVE_TO_DT
	then taba.EFFECTIVE_TO_DT
	else tabb.EFFECTIVE_TO_DT
	end as EFFECTIVE_TO_DT, taba.EFFECTIVE_FROM_DT as ef_fr1, 

      tabb.EFFECTIVE_FROM_DT as ef_fr2
		 
from T1 taba 
right outer join T2 tabb 
		    on (taba.DEAL_RK=tabb.DEAL_RK
			 and taba.EFFECTIVE_FROM_DT <= tabb.EFFECTIVE_TO_DT 
			 and taba.EFFECTIVE_TO_DT >= tabb.EFFECTIVE_FROM_DT)


Проблема заключается в там, что при пересечении по временным промежуткам происходит очень существенное увеличение количества одинаковых строк, так как их много и временные промежутки EFFECTIVE_FROM_DT и EFFECTIVE_TO_DT бывают довольно длинными.
Возможно, есть идеи по дополнительному условию в джоине, которое поможет хоть как то ограничить выборку. Таблицы имеют только те 3 поля, которые используются при джоине

К сообщению приложен файл. Размер - 12Kb
14 янв 15, 12:01    [17115595]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
baza906
Возможно, есть идеи по дополнительному условию в джоине, которое поможет хоть как то ограничить выборку.

В смысле придумать за вас, сколько и каких записей нужно выбрать ?
14 янв 15, 12:05    [17115640]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
aleks2
Guest
Ну, разучи outer apply и top(1).
14 янв 15, 12:06    [17115650]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Добрый Э - Эх
Guest
лучше бы привел юзабильный набор тестовых данных и желаемый результат на них.
в целом, не понятен смысл решаемой задачи. но есть подозрение, что внешнее соединение ты зря вкорячил.
14 янв 15, 12:07    [17115660]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8819
baza906, используйте exists, например.
14 янв 15, 12:27    [17115809]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
Добрый Э - Эх,тип соединения передается с параметром хранимой процедуры, запрос генерируется динамически
14 янв 15, 12:36    [17115873]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
хмхмхм
Guest
baza906
Добрый Э - Эх,тип соединения передается с параметром хранимой процедуры, запрос генерируется динамически


т.е. надо оптимизировать запрос, не меняя сам запрос?
14 янв 15, 12:45    [17115955]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
select 
 ISNULL(tabb.DEAL_RK,taba.DEAL_RK) AS DEAL_RK
,MAX(f.EFFECTIVE_FROM_DT) as EFFECTIVE_FROM_DT
,MIN(t.EFFECTIVE_TO_DT) as EFFECTIVE_TO_DT
from T1 taba 
full outer join T2 tabb 
		    on (taba.DEAL_RK=tabb.DEAL_RK
			 and taba.EFFECTIVE_FROM_DT <= tabb.EFFECTIVE_TO_DT 
			 and taba.EFFECTIVE_TO_DT >= tabb.EFFECTIVE_FROM_DT)
cross apply(select * from (values(taba.EFFECTIVE_FROM_DT),(tabb.EFFECTIVE_FROM_DT)) t(EFFECTIVE_FROM_DT)) f
cross apply(select * from (values(taba.EFFECTIVE_TO_DT),(tabb.EFFECTIVE_TO_DT)) t(EFFECTIVE_TO_DT)) t
group by ISNULL(taba.DEAL_RK,DEAL_RK)
,ISNULL(taba.EFFECTIVE_FROM_DT,tabb.EFFECTIVE_FROM_DT)
,ISNULL(taba.EFFECTIVE_TO_DT,tabb.EFFECTIVE_TO_DT)
14 янв 15, 12:46    [17115968]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
Добрый Э - Эх,

К сообщению приложен файл. Размер - 46Kb
14 янв 15, 13:05    [17116125]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
LexusR, спасибо, сейчас потестирую
14 янв 15, 13:06    [17116144]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Владислав Колосов
Member

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

и где в результате одинаковые строки? Ни одной не вижу.
14 янв 15, 13:07    [17116148]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Добрый Э - Эх
Guest
baza906,

я, конечно, альтруист, но не до такой степени, чтобы вручную твои картинки в текст переколачивать. под юзабильным имелось ввиду - готовым к использованию посредством банального копи-пастинга из окна веб-браузера в окно запросовыполнялки.
14 янв 15, 13:11    [17116182]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Добрый Э - Эх,

а шо слабо ?
14 янв 15, 13:13    [17116195]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Добрый Э - Эх,

есть же FineReader!
14 янв 15, 13:25    [17116259]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
Добрый Э - Эх, ааа, не понял тебя)

результат
1 1900-01-01 00:00:00.000 2008-08-20 23:59:59.000
1 2008-08-21 00:00:00.000 2008-09-04 23:59:59.000
1 2008-09-05 00:00:00.000 2009-02-09 23:59:59.000
1 2009-02-10 00:00:00.000 5999-01-01 00:00:00.000
2 1900-01-01 00:00:00.000 2008-09-07 23:59:59.000
2 2008-09-08 00:00:00.000 2008-09-22 23:59:59.000
2 2008-09-23 00:00:00.000 2008-10-05 23:59:59.000
2 2008-10-06 00:00:00.000 2008-10-06 23:59:59.000
2 2008-10-07 00:00:00.000 2008-10-20 23:59:59.000
2 2008-10-21 00:00:00.000 2009-02-09 23:59:59.000
2 2009-02-10 00:00:00.000 5999-01-01 00:00:00.000


Т1
2 2008-10-06 00:00:00.000 2008-10-06 23:59:59.000
2 2008-10-07 00:00:00.000 5999-01-01 00:00:00.000

Т2
1 1900-01-01 00:00:00.000 2008-08-20 23:59:59.000
1 2008-08-21 00:00:00.000 2008-09-04 23:59:59.000
1 2008-09-05 00:00:00.000 2009-02-09 23:59:59.000
1 2009-02-10 00:00:00.000 5999-01-01 00:00:00.000
2 1900-01-01 00:00:00.000 2008-09-07 23:59:59.000
2 2008-09-08 00:00:00.000 2008-09-22 23:59:59.000
2 2008-09-23 00:00:00.000 2008-10-05 23:59:59.000
2 2008-10-06 00:00:00.000 2008-10-20 23:59:59.000
14 янв 15, 13:26    [17116269]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
есть же FineReader!

Ответы тогда предлагаю давать в прозе. Можно и в стихах, если кто осилит
Например
Писал Гаврила раз запрос
И у него возник вопрос
...
14 янв 15, 13:27    [17116271]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Добрый Э - Эх
Guest
iap
Добрый Э - Эх,

есть же FineReader!
я это учту, когда буду выкладывать ответ автору в виде картинки... ;)
14 янв 15, 13:28    [17116279]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
Владислав Колосов, суть не в том. В один большой промежуток (которых здесь не случилось), может попасть 100 маленьких. Я по этому и уточнил, может ли кто-нибудь посоветовать способ, как можно сделать условие джоина более точным, чем нынешний вариант, дабы уменьшить количество совпадений. К примеру, джойнить только по месяцам и т.д., разбивая на них все промежутки (был такой вариант, не прокатил).
14 янв 15, 13:31    [17116307]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Добрый Э - Эх
Guest
baza906,

преобразовать "мелкую" таблицу из интервалов в точки, внешне пересечь "крупную таблицу" с полученными точками, при наличии пересечения решить, какое из значений начал/кончал брать для итогового интервала.

З.Ы.
завтра фотошоп поставлю, картинку нарисую...
14 янв 15, 13:57    [17116525]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
Добрый Э - Эх, там разные входные таблицы, не всегда получится их разделить на мелкую и крупную((
14 янв 15, 14:22    [17116742]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
declare @T1 table (DEAL_RK int,EFFECTIVE_FROM_DT datetime, EFFECTIVE_TO_DT datetime)
declare @T2 table (DEAL_RK int,EFFECTIVE_FROM_DT datetime, EFFECTIVE_TO_DT datetime)
insert into @T1 values
 (2, '2008-10-06 00:00:00.000', '2008-10-06 23:59:59.000')
,(2, '2008-10-07 00:00:00.000', '5999-01-01 00:00:00.000')
insert into @T2 values
 (1,'1900-01-01 00:00:00.000','2008-08-20 23:59:59.000')
,(1,'2008-08-21 00:00:00.000','2008-09-04 23:59:59.000')
,(1,'2008-09-05 00:00:00.000','2009-02-09 23:59:59.000')
,(1,'2009-02-10 00:00:00.000','5999-01-01 00:00:00.000')
,(2,'1900-01-01 00:00:00.000','2008-09-07 23:59:59.000')
,(2,'2008-09-08 00:00:00.000','2008-09-22 23:59:59.000')
,(2,'2008-09-23 00:00:00.000','2008-10-05 23:59:59.000')
,(2,'2008-10-06 00:00:00.000','2008-10-20 23:59:59.000')
,(2,'2008-10-21 00:00:00.000','2009-02-09 23:59:59.000')
,(2,'2009-02-10 00:00:00.000','5999-01-01 00:00:00.000')

;WITH T(DEAL_RK,EFFECTIVE_DT,S) AS( 
select distinct DEAL_RK,EFFECTIVE_FROM_DT as EFFECTIVE_DT ,1 as s FROM @T1
UNION select distinct DEAL_RK,EFFECTIVE_TO_DT ,2 as s  FROM @T1
UNION select distinct DEAL_RK,EFFECTIVE_FROM_DT,1 as s  FROM @T2
UNION select distinct DEAL_RK,EFFECTIVE_TO_DT,2 as s  FROM @T2
)
SELECT DEAL_RK,t1.EFFECTIVE_DT as EFFECTIVE_FROM_DT
,tt.EFFECTIVE_DT as EFFECTIVE_TO_DT
FROM T T1
CROSS APPLY
(SELECT TOP 1  EFFECTIVE_DT FROM T T2 WHERE T2.DEAL_RK = T1.DEAL_RK
AND T2.S = 2 AND T2.EFFECTIVE_DT > T1.EFFECTIVE_DT ORDER BY EFFECTIVE_DT ASC) tt 
WHERE T1.S=1
ORDER BY T1.DEAL_RK,T1.EFFECTIVE_DTdeclare @T1 table (DEAL_RK int,EFFECTIVE_FROM_DT datetime, EFFECTIVE_TO_DT datetime)
declare @T2 table (DEAL_RK int,EFFECTIVE_FROM_DT datetime, EFFECTIVE_TO_DT datetime)
insert into @T1 values
 (2, '2008-10-06 00:00:00.000', '2008-10-06 23:59:59.000')
,(2, '2008-10-07 00:00:00.000', '5999-01-01 00:00:00.000')
insert into @T2 values
 (1,'1900-01-01 00:00:00.000','2008-08-20 23:59:59.000')
,(1,'2008-08-21 00:00:00.000','2008-09-04 23:59:59.000')
,(1,'2008-09-05 00:00:00.000','2009-02-09 23:59:59.000')
,(1,'2009-02-10 00:00:00.000','5999-01-01 00:00:00.000')
,(2,'1900-01-01 00:00:00.000','2008-09-07 23:59:59.000')
,(2,'2008-09-08 00:00:00.000','2008-09-22 23:59:59.000')
,(2,'2008-09-23 00:00:00.000','2008-10-05 23:59:59.000')
,(2,'2008-10-06 00:00:00.000','2008-10-20 23:59:59.000')
,(2,'2008-10-21 00:00:00.000','2009-02-09 23:59:59.000')
,(2,'2009-02-10 00:00:00.000','5999-01-01 00:00:00.000')

;WITH T(DEAL_RK,EFFECTIVE_DT,S) AS( 
select distinct DEAL_RK,EFFECTIVE_FROM_DT as EFFECTIVE_DT ,1 as s FROM @T1
UNION select distinct DEAL_RK,EFFECTIVE_TO_DT ,2 as s  FROM @T1
UNION select distinct DEAL_RK,EFFECTIVE_FROM_DT,1 as s  FROM @T2
UNION select distinct DEAL_RK,EFFECTIVE_TO_DT,2 as s  FROM @T2
)
SELECT DEAL_RK,t1.EFFECTIVE_DT as EFFECTIVE_FROM_DT
,tt.EFFECTIVE_DT as EFFECTIVE_TO_DT
FROM T T1
CROSS APPLY
(SELECT TOP 1  EFFECTIVE_DT FROM T T2 WHERE T2.DEAL_RK = T1.DEAL_RK
AND T2.S = 2 AND T2.EFFECTIVE_DT > T1.EFFECTIVE_DT ORDER BY EFFECTIVE_DT ASC) tt 
WHERE T1.S=1
ORDER BY T1.DEAL_RK,T1.EFFECTIVE_DT
14 янв 15, 14:59    [17117123]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Добрый Э - Эх
Guest
baza906
Добрый Э - Эх, там разные входные таблицы, не всегда получится их разделить на мелкую и крупную((

на самом деле - это не важно. алгоритм в общем случае - симметричный. работать будет в обе стороны. это вообще общий подход при решении широкого класса задач на интервалы. в особенности, если требуется пересекающиеся интервалы преобразовать в непересекающиеся.
14 янв 15, 15:00    [17117136]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
Добрый Э - Эх, обязательно попробую и сообщу о результатах
14 янв 15, 15:20    [17117319]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3754
baza906
Добрый Э - Эх, обязательно попробую и сообщу о результатах

а что тебя сейчас не устраивает?
p.s. больше и равно на больше замени
14 янв 15, 16:19    [17117901]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
baza906
Member

Откуда:
Сообщений: 283
Ivan Durak, я выше писал, что не устраивает. Начало и конец у нас никогда не совпадут, из конца всегда вычитается секунда
14 янв 15, 16:35    [17118034]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить