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

Откуда:
Сообщений: 11
Здравствуйте, есть запрос
SELECT TOP 200 p.id as idPoch,CASE WHEN p.id_depo_from > 0 THEN ISNULL(d.naim,'') ELSE ISNULL(k1.naim,'') END
  as [Детали поступили от],
d3.naim as[Заведено в],p.data_doc as [Дата документа],
 p.nm_doc as[Номер документа], isnull(cast(tdt.docid_in as varchar),tpi.torekid) [Пакет ИИТ],ISNULL(k.naim,'')+' № ' +ISNULL(dg.naim,'') +' от '+CAST(YEAR(dg.data_dog) AS VARCHAR) as [Договор], 
 p.info as [Информация],p.is_closed,p.code_asu as[Код асу врк],isnull(p.stat,0) stat,(SELECT COUNT(*) FROM pochinka_detali pd WHERE pd.id_pochinka =p.id) as [Деталей в заявке]
, p.total_prise as [Итоговая сумма] 
 FROM pochinka p 
 INNER JOIN depo d ON (d.id = p.id_depo_from) 
 LEFT JOIN kontr k1 ON (k1.id = -p.id_depo_from) 
 LEFT JOIN kontr k2 ON(k2.id = -p.id_pto) 
 LEFT join dogovor dg ON (dg.id = p.id_dogovor)
 LEFT join kontr k ON (k.id = dg.id_kontr) 
 LEFT join depo d2 ON (d2.id = dg.id_depo) 
 LEFT join torek_doc_to tdt ON (tdt.docid = p.id) and (replace(tdt.type,'B','')=tdt.type) 
 LEFT JOIN torek_doc_app tda ON tda.id = p.doc_id1 LEFT JOIN torek_paket tp ON tp.id = tda.id_torek_paket LEFT JOIN torek_paket_in tpi ON tpi.id = tp.id_torek_paket_in 
 LEFT JOIN pto ON(p.id_pto=pto.id)  
 LEFT JOIN depo d3 ON (d3.id = p.id_depo) WHERE 1=1 and p.id_depo in(156,150,155,154,284,283,140,135,137,1,285,286,66,53,29,42,16,32,113,103,83,12,74,51,108,28,34,95,117,99,72,10,57,8,55,130,25,70,82,45,9,60,77,76,105,116,15,121,129,125,85,65)and p.data_doc>= '01.04.2017' and p.data_doc<='03.05.2017'  and p.doc_type = 1 and p.id_depo_from is not null


Судя по графику выполнения высокая стоимость на сканировании кластерного индекса [torek_doc_to],из-за чего думаю запрос и выполняется несколько минут. Дефрагментация индексов ускоряет выполнение запроса, но этого надолго не хватает, так как ко всем таблицам идет большое обращение с CREATE, UPDATE, DELETE. Подскажите пожалуйста, можно ли как-то оптимизировать запрос или же надо смотреть в оптимизацию.обслуживание самой БД?
20 апр 17, 08:43    [20417203]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

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

К сообщению приложен файл. Размер - 86Kb
20 апр 17, 08:44    [20417204]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Ligeros905,

рекомендацию зелененьким в плане, ни в коем случае не выполняйте
20 апр 17, 08:48    [20417211]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

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

Спасибо, учту. я вообще думаю, что нецелесообразно было везде создать кластерные индексы.
20 апр 17, 09:06    [20417274]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
vborets
Member

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

и что это за странное условие (replace(tdt.type,'B','')=tdt.type) ?
20 апр 17, 10:46    [20417651]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Mr. X
Guest
Ligeros905,

Жесть, учить правила написания запросов, поисковые предикаты и всё такое...
20 апр 17, 10:56    [20417714]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

Откуда:
Сообщений: 11
Mr. X,

Я правильно понимаю, что сам запрос написан некорректно? Данный запрос не мое творение, поэтому мне интересно узнать максимально, что не так и на что акцентировать внимание, знания
20 апр 17, 11:23    [20417876]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
o-o
Guest
по огрызку плана что ли лечить надо?
план давайте целиком и актуальный.
список in сложите в табл. переменную, ее соединяйте, все лучше, чем 1000 значений in
20 апр 17, 11:27    [20417913]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Ligeros905,

Корректно или нет - это решать вам.
Никто же не знает, что вы хотите получить в запросе.

Вопросы по производительности лучше сопровождать планами (не картинками), приложить план можно через стандартную форму ответа на форуме, приложить файл .sqlplan.

Судя по 1=1 это ОРМ (или подобный ему) генерирует запрос?

Если запрос критичен, возможно, стоит отказаться от авто генерации, насколько я помню, даже в самых махровых ОРМ есть возможность прописать запрос прямо, без генерации. Если так, то пишете запрос, выполняете, смотрите когда начинает тормозить (если будет тормозить) и выкладываете сюда планы, до того как тормозит и после.

Если у вас не ОРМ и вы сами это написали - то мое сочувствие. Возможно нужно пересмотреть подход к написанию запросов, например в части IN и в части логических типов LEFT.
20 апр 17, 11:34    [20417958]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
replace(tdt.type,'B','')=tdt.type

это приводит к сканированию.
20 апр 17, 11:35    [20417966]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Владислав Колосов
replace(tdt.type,'B','')=tdt.type

это приводит к сканированию.
k1.id = -p.id_depo_from
тоже :((
20 апр 17, 11:47    [20418033]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
waszkiewicz
Member

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

про "логических типов LEFT" что имелось в виду?
20 апр 17, 12:16    [20418156]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
waszkiewicz,

Имелось ввиду, что может не надо LEFT, а можно INNER.

Оптимизатор имеет более ограниченное число перестановок соединения когда они внешние, но менее ограниченное, когда внутренние (кстати, часто бывает обратный эффект, пишут left, у оптимизатора меньше вариантов и вариант с left оказывается быстрее, тогда обычно пишут что "left быстрее inner" что является заблуждением и обычно "зависит"). Так что мой посыл был, может не нужно столько внешних соединений, может где-то можно обойтись внутренними.
20 апр 17, 12:53    [20418369]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Mr. X
Guest
o-o,
Правильнее, ИМХО, во #табл. Ибо не известно ск-ко будет строк 1000 или 100....00
20 апр 17, 12:56    [20418382]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
SomewhereSomehow,
спасибо
20 апр 17, 13:03    [20418417]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
автор
left быстрее inner

Да, был такой случай. А-ля "мягкий хинт" получилось.
20 апр 17, 13:09    [20418459]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

Откуда:
Сообщений: 11
Владислав Колосов
replace(tdt.type,'B','')=tdt.type

это приводит к сканированию.


 LEFT hash join torek_doc_to tdt ON (tdt.docid = p.id) and (replace(tdt.type,'B','')=tdt.type) 


Добавил к join'у hash аргумент и запрос стал выполняться за пару секунд
20 апр 17, 16:26    [20419514]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
o-o
Guest
Ligeros905
Владислав Колосов
replace(tdt.type,'B','')=tdt.type

это приводит к сканированию.


 LEFT hash join torek_doc_to tdt ON (tdt.docid = p.id) and (replace(tdt.type,'B','')=tdt.type) 


Добавил к join'у hash аргумент и запрос стал выполняться за пару секунд

т.е. уже скан torek_doc_to ни при чем, так?
ведь именно для hash join вычитывается таблица целиком.
а как приятно было погадать на кофейной гуще и обвинить во всем кластерный индекс, правда?
а еще мог его и снести, судя по
автор
я вообще думаю, что нецелесообразно было везде создать кластерные индексы
20 апр 17, 16:37    [20419567]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
o-o
Guest
a еще я подозреваю, что на первоначальной картинке хэш и был,
ибо русская студия переводит NL, как видно на той же картинке,
Merge Join заканчивался бы на "join",
а вот hash join он и есть Hash Match,
от него мы и видим "tch" на огрызке плана
20 апр 17, 16:42    [20419579]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

Откуда:
Сообщений: 11
o-o
Ligeros905
пропущено...


 LEFT hash join torek_doc_to tdt ON (tdt.docid = p.id) and (replace(tdt.type,'B','')=tdt.type) 


Добавил к join'у hash аргумент и запрос стал выполняться за пару секунд

т.е. уже скан torek_doc_to ни при чем, так?
ведь именно для hash join вычитывается таблица целиком.
а как приятно было погадать на кофейной гуще и обвинить во всем кластерный индекс, правда?
а еще мог его и снести, судя по
автор
я вообще думаю, что нецелесообразно было везде создать кластерные индексы


Как же я его снесу, если там индекс только на Primary Key
20 апр 17, 16:54    [20419623]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

Откуда:
Сообщений: 11
o-o,

но с hash JOIN кластерный индекс наконец-то сработал по своему прямому назначению
20 апр 17, 16:58    [20419640]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

Откуда:
Сообщений: 11
Спасибо большое всем! :)
20 апр 17, 16:59    [20419646]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
o-o
Guest
Ligeros905
Как же я его снесу, если там индекс только на Primary Key

да вот так вот просто:
если это constraint, то
alter table dbo.torek_doc_to
drop constraint pk_torek_doc_to

если просто unique clustered index,
то
drop index pk_torek_doc_to on dbo.torek_doc_to

хотя это просто ответ на ваш вопрос и вовсе не рекомендация.
это есть дурацкий вредный совет в большинстве случаев
20 апр 17, 17:05    [20419666]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
o-o
Guest
Ligeros905
но с hash JOIN кластерный индекс наконец-то сработал по своему прямому назначению

да блин, и до этого в плане HASH MATCH torek_doc_to,
хоть картинка и обрезана
20 апр 17, 17:07    [20419676]     Ответить | Цитировать Сообщить модератору
 Re: Помощь новичка в оптимизации  [new]
Ligeros905
Member

Откуда:
Сообщений: 11
o-o
Ligeros905
но с hash JOIN кластерный индекс наконец-то сработал по своему прямому назначению

да блин, и до этого в плане HASH MATCH torek_doc_to,
хоть картинка и обрезана


Хорошо, главное не горячитесь. Извиняюсь, за свою глупость, но пока еще очень зелёный
20 апр 17, 17:15    [20419706]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить