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

Откуда: Москва
Сообщений: 215
Доброго дня.
Давно не писал на SQL и что-то не могу придумать, как иначе переписать этот скрипт?
Суть скрипта в том, что он отбирает счета клиента с минимальной датой открытия.

select i.Brief,r.Brief,r.DateStart
  from tInstitution  i
 inner join
       tResource     r 
    on r.InstOwnerID  = i.InstitutionID
   and substring(r.brief,1,5) in ('40701','40702','40703','40807')
   and r.BalanceID    = 2140
   and r.DateStart <= '20130630'
   and r.DateStart = (select min(r_min.DateStart)
                        from tResource r_min
                       where 1=1
                         and r_min.InstOwnerID = i.InstitutionID
                         and substring(r_min.brief,1,5) in ('40701','40702','40703','40807')
                         and r_min.BalanceID    = 2140
                         and r_min.DateEnd     = '19000101'
                         and r_min.FundID          = 2)
   and r.DateEnd      = '19000101'
   and r.FundID       = 2
 where i.PropDealPart = 1
order by 1
8 май 15, 11:18    [17616967]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
quest_123456
Guest
Azvaal,

top 1 with ties + order by(ваше поле даты)?
8 май 15, 11:29    [17617033]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
Merdoc
Member

Откуда: Новосибирск
Сообщений: 103
Azvaal,
А можно план глянуть?
8 май 15, 11:29    [17617036]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
quest_123456
Guest
Azvaal,

забыл про row_number()
8 май 15, 11:30    [17617045]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
SELECT i.Brief, r.*
FROM dbo.tInstitution i
CROSS APPLY (
	SELECT TOP(1) r.Brief, r.DateStart
	FROM dbo.tResource r
	WHERE LEFT(r.brief, 5) IN ('40701', '40702', '40703', '40807')
		AND r.BalanceID = 2140
		AND r.DateStart <= '20130630'
		AND r.DateEnd = '19000101'
		AND r.FundID = 2
		AND r.InstOwnerID = i.InstitutionID
	ORDER BY r.DateStart
) t2
WHERE i.PropDealPart = 1
ORDER BY i.Brief


Без плана выполнения - это как пальцев в небо.
8 май 15, 11:32    [17617063]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
Crimean
Member

Откуда:
Сообщений: 13147
and substring(r_min.brief,1,5) in ('40701','40702','40703','40807')
LIKE же просится
8 май 15, 11:32    [17617066]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
Merdoc
Azvaal,
А можно план глянуть?


К сообщению приложен файл. Размер - 33Kb
8 май 15, 11:36    [17617095]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Crimean
and substring(r_min.brief,1,5) in ('40701','40702','40703','40807')
LIKE же просится
Семёрка с восьмёркой мешаются.
Придётся OR применять - всё равно плохо получится.
Разве что UNIONом дальше оптимизировать
8 май 15, 11:40    [17617114]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Так может стоит добавить PK для tResource?
8 май 15, 11:40    [17617117]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
iap
Crimean
and substring(r_min.brief,1,5) in ('40701','40702','40703','40807')
LIKE же просится
Семёрка с восьмёркой мешаются.
Придётся OR применять - всё равно плохо получится.
Разве что UNIONом дальше оптимизировать
Хотя,
EXISTS(SELECT * FROM(VALUES('4070[123]%'),('40807%'))T(Mask) WHERE r_min.brief LIKE T.Mask)
8 май 15, 11:43    [17617135]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
Merdoc
Member

Откуда: Новосибирск
Сообщений: 103
iap,
А это быстрее? О_о
8 май 15, 11:45    [17617143]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
Azvaal
Member

Откуда: Москва
Сообщений: 215
AlanDenton
Так может стоит добавить PK для tResource?


Что такое PK? Ваш запрос отрабатывает дольше, нежели мой :)
8 май 15, 11:47    [17617154]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Merdoc
iap,
А это быстрее? О_о
Не знаю.
Во-первых, мы не знаем, проиндексировано ли r_min.brief.
Во-вторых, можно ещё, как я писал перед этим,
(r_min.brief LIKE '40701%' OR r_min.brief LIKE '40702%' OR r_min.brief LIKE '40703%' OR r_min.brief LIKE '40807%')
после чего оптимизировать эти ORы UNIONами.
Это будет громоздко, но, возможно, быстрее. Ибо будет возможность искать по индексу
8 май 15, 11:51    [17617180]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
автор
Что такое PK?


Кластерный индекс и ограничение юник, если по уму отвечать. Неужели гугл уже не в почете.

автор
Ваш запрос отрабатывает дольше, нежели мой :)


Это не удивительно. Для каждой строки tInstitution будет делаться TableScan из tResource. А если были бы индексы, то мы бы получилили Index Seek из tResource.
8 май 15, 11:53    [17617193]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
AlanDenton
Кластерный индекс и ограничение юник, если по уму отвечать. Неужели гугл уже не в почете
Почему именно кластерный?
Почему именно CONSTRAINT UNIQUE? Есть же CONSTRAINT PRIMARY KEY.
А хватит и просто уникального индекса.
8 май 15, 11:56    [17617223]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
Azvaal
Member

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

XAK1tResource	nonclustered, unique located on PRIMARY	Brief, ParentMask, InstitutionID, FundID, DateEnd
XAK2tResource	nonclustered, unique located on PRIMARY	ResourceType, BalanceID, InstitutionID, FundID, ParentMask, Brief, DateEnd
XAK3tResource	nonclustered, unique located on PRIMARY	ParentID, InstitutionID, FundID, ResHash, DateEnd
XAK4tResource	nonclustered, unique located on PRIMARY	ResourceType, BalanceID, InstitutionID, AccOrder, DateEnd
XIE10tResource	nonclustered located on PRIMARY	UserMainID
XIE11tResource	nonclustered located on PRIMARY	ParentID, InstitutionID, FundID, Brief
XIE1tResource	nonclustered located on PRIMARY	ParentHash
XIE2tResource	nonclustered located on PRIMARY	InstOwnerID, ParentID
XIE3tResource	nonclustered located on PRIMARY	ResBenefID
XIE4tResource	nonclustered located on PRIMARY	InstBenefID, InstitutionID, FundID
XIE5tResource	nonclustered located on PRIMARY	ParentID, FundID, ResourceType
XIE6tResource	nonclustered located on PRIMARY	InstitutionID, InstBenefID, FundID
XIE7tResource	nonclustered located on PRIMARY	AccAnlID
XIE8tResource	nonclustered located on PRIMARY	DealProtocolID
XIE9tResource	nonclustered located on PRIMARY	InstitutionID, FundID, DefaultAcc
XPKtResource	nonclustered, unique located on PRIMARY	ResourceID
8 май 15, 11:58    [17617234]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
автор
Почему именно кластерный?


Я бы начал с него. У нас даже структуры таблиц нету, чтобы дать толковый совет что да как.

И Вы правы. Уникальный индекс там очень сильно напрашивается в гости.
8 май 15, 11:58    [17617235]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
AlanDenton
И Вы правы. Уникальный индекс там очень сильно напрашивается в гости.
В данном случае я просто перечислил возможные определения PK и его аналогов.
Не имел в виду данный конкретный запрос. Спрашивали же "что такое PK?"
8 май 15, 12:02    [17617267]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
хмхмхм
Guest
Azvaal
Доброго дня.
Давно не писал на SQL и что-то не могу придумать, как иначе переписать этот скрипт?
Суть скрипта в том, что он отбирает счета клиента с минимальной датой открытия.

select i.Brief,r.Brief,r.DateStart
  from tInstitution  i
 inner join
       tResource     r 
    on r.InstOwnerID  = i.InstitutionID
   [color=yellow]and substring(r.brief,1,5) in ('40701','40702','40703','40807')
[/color]   and r.BalanceID    = 2140
   and r.DateStart <= '20130630'
   and r.DateStart = (select min(r_min.DateStart)
                        from tResource r_min
                       where 1=1
                         and r_min.InstOwnerID = i.InstitutionID
                         and substring(r_min.brief,1,5) in ('40701','40702','40703','40807')
                         and r_min.BalanceID    = 2140
                         and r_min.DateEnd     = '19000101'
                         and r_min.FundID          = 2)
   and r.DateEnd      = '19000101'
   and r.FundID       = 2
 where i.PropDealPart = 1
order by 1


Зачем же так жестоко? Чем like '12345%' не подошел?
8 май 15, 12:31    [17617448]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
хмхмхм
Guest
Azvaal,

кстати, на 3 разных select-а не пробовали разбить?
8 май 15, 12:35    [17617473]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизировать запрос  [new]
__Avenger__
Member

Откуда:
Сообщений: 2006
Замени substring на ParentID IN ()

select distinct ParentID from tResource 
where substring(brief,1,5) in ('40701','40702','40703','40807')


Сам запрос:
SELECT t.* 
FROM (
select i.Brief AS InstBrief,r.Brief,r.DateStart, ROW_NUMBER() OVER (PARTITION BY i.InstitutionID ORDER BY r.DateStart DESC) AS RowID
  from tInstitution  i
 inner join
       tResource     r WITH (NOLOCK, INDEX(XIE2tResource)) 
    on r.InstOwnerID  = i.InstitutionID
   and r.ParentID IN (...)
   and r.BalanceID    = 2140
   and r.DateStart   <= '20130630'
   and r.DateEnd      = '19000101'
   and r.FundID       = 2
 where i.PropDealPart = 1
) t
WHERE t.RowID = 1
order by 1
10 май 15, 01:16    [17622917]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить