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

Откуда:
Сообщений: 30
Коллеги, подскажите, куда копать и из-за чего может быть такая ситуация:

Есть простой запрос (исходный был конечно более сложный, но суть его такая же)
Select * from dbo.[Новый транзит] where [Из города]='Москва' or [В город]='Москва'
Выполняется приемлемо быстро. Исходная таблица с большим количеством накладных. Индексы построены.

Если меняем 'Москва' на 'Екатеринбург' запрос отрабатывает в РАЗЫ медленнее!
Планы выполнения при этом разные.

Как такое может быть? И что с этим делать?

К сообщению приложен файл. Размер - 36Kb
26 сен 19, 12:20    [21979659]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

Откуда:
Сообщений: 30
Только что обнаружил, что
на производительность влияет условие
[В город] = 'Москва' - работает быстро
[В город] = 'Екатеринбург' - работает медленно
Индекс по полю "В город" пересоздавал и реорганизовывал - ничего не поменялось
26 сен 19, 12:37    [21979686]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
invm
Member

Откуда: Москва
Сообщений: 9349
Статистику обновите (желательно с full scan) по индексам [Из города] и [в город]
26 сен 19, 12:37    [21979687]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

Откуда:
Сообщений: 30
К сожалению никак не помогло...
26 сен 19, 13:16    [21979725]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Соколов Валерий,

OPTION (RECOMPILE) :)
26 сен 19, 13:23    [21979735]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
invm
Member

Откуда: Москва
Сообщений: 9349
TaPaK
OPTION (RECOMPILE)
С литеральными параметрами?

Соколов Валерий
К сожалению никак не помогло...
Планы показывайте. Актуальные, в формате sqlplan.
26 сен 19, 13:44    [21979775]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1367
Соколов Валерий,

опрометчивое решение тестировать производительность на select *

вам действительно нужны все столбцы из таблицы?
26 сен 19, 13:56    [21979801]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
felix_ff
Соколов Валерий,

опрометчивое решение тестировать производительность на select *

вам действительно нужны все столбцы из таблицы?
+1

Еще избавьтесь от OR. Сервер плохо его понимает. Замените на два запроса соединенных через UNION или UNION ALL, в зависимости от данных и бизнес логики. UNION ALL быстрее, но нужно убедиться что [Из города] никогда не равно [В город], ну или тупо исключить фильтром в одном из запросов.
26 сен 19, 22:47    [21980361]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

Откуда:
Сообщений: 30
Попытаюсь всем ответить как могу :)

1. Статистику таблицы по столбцам [Из города], [В город] обновлял - результаты те же, индексы перестраивал
2. OPTION (RECOMPILE) в SELECTе применял - никаких изменений
3. Я производительность не тестирую. Выбираю все столбцы просто что бы упростить запрос для понимания.
4. Сам запрос такой:

SELECT top 2000 [новый транзит].*
FROM         dbo.контрагенты AS Отправитель RIGHT OUTER JOIN
                      dbo.контрагенты AS Получатель RIGHT OUTER JOIN
                      dbo.[контрагенты - адреса] AS СкладПолучателя RIGHT OUTER JOIN
                      dbo.[новый транзит] ON СкладПолучателя.[ID адреса] = dbo.[новый транзит].[Получатель склад] ON 
                      Получатель.[№_клиента] = dbo.[новый транзит].[код клиента пол] ON Отправитель.[№_клиента] = dbo.[новый транзит].[код клиента] LEFT OUTER JOIN
                      dbo.контрагенты AS Плательщик ON dbo.[новый транзит].[код плательщика] = Плательщик.[№_клиента] LEFT OUTER JOIN
                      dbo.[контрагенты - адреса] AS СкладОтправителя ON dbo.[новый транзит].[Отправитель склад] = СкладОтправителя.[ID адреса]
WHERE     
Плательщик.[Регион выст счетов] ='Екатеринбург'
OR
 dbo.[новый транзит].[Из города]  ='Екатеринбург'
OR                                                           
dbo.[новый транзит].[В город]  ='Екатеринбург'



На всякий случай сообщаю:
Когда делаю выборку по "Москве" - возвращаемых записей порядка 400 000, по "Екатеринбургу" - всего 1 900 штук
В запросе делаю TOP 2000

Прикладываю планы выполнения.
Упростив запросы увидел что планы по структуре одинаковые, но смутило то что, операция "Просмотр строк таблицы [Новый транзит]" гораздо больше по стоимости когда выборка идет по Екатеринбургу. При этом показатель "Фактическое количество строк" примерно 700 000, по Москве - около 8 000. Что это значит - не понимаю!

Как только меняю "В город" на Москву - все начинает летать.

Сообщение было отредактировано: 27 сен 19, 01:20
26 сен 19, 23:51    [21980408]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Gerros
Member

Откуда: Харьков
Сообщений: 501
Соколов Валерий,

проверьте количество чтений для обоих запросов.

А пока что - задача:
Представьте себе склад (это файл БД), а в нём ящики (это страницы), и в каждом ящике по сто фруктов (это строки). Фрукты в ящиках могут быть красные (Москва) или жёлтые (не Москва), причём в среднем в каждом ящике девяносто красных и десять жёлтых. Логично предположить, что чтобы достать сто красных фруктов, со склада достаточно принести примерно два ящика.
Сколько ящиков нужно принести, чтобы достать сто жёлтых фруктов?
27 сен 19, 00:44    [21980425]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1367
Соколов Валерий,

еще раз: вам реально нужны все столбцы из ваших таблиц?

дело в том что к примеру
select * from table where id = 1


будет сильно отличаться по плану от
select [name] from table where id = 1


селект с звездочкой выбирает все колонки таблицы, мало вероятно что у вас везде в предикате все выводится на поиск по кластеризованным индексам. в таком случае вы не оставляете оптимизатору большого выбора поскольку rid/key-lookup дорогостоящие операции, основная оценка будет происходить из кардинальности по предикату. для достаточно большого объема оптимизатор выберет сканирование таблицы один раз что собственно и видно у вас по предикату где город "москва"

но вот для относительно малого объема будет выбираться поиск + rid/key lookup что может дать достаточно существенную деградацию.

установите
set statistics io on

и сравните логические чтения когда идет сканирование таблицы и когда идет запрос по seek+lookup

второй вариант выгоден на относительно малых объемах строк
27 сен 19, 02:11    [21980431]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36972
Расскажите уже кто-нибудь ТС про forceseek.
27 сен 19, 02:23    [21980434]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1367
Гавриленко Сергей Алексеевич,

так у него с сиками как раз и тормозит на сколько я понял из постов выше
27 сен 19, 02:24    [21980435]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36972
felix_ff,

Тогда рассказывать надо про forcescan, и про то, что не надо пудрить приличной публике мозги.
27 сен 19, 02:30    [21980438]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1367
Гавриленко Сергей Алексеевич
felix_ff,

Тогда рассказывать надо про forcescan, и про то, что не надо пудрить приличной публике мозги.


это конечно да, но если ему реально потом понадобится 2-3 колонки из всего зверинца план со сканом в итоге проиграет.

я все к тому что имхо достаточно странно пытаться искать оптимальный план пока нет действительного конечного запроса
27 сен 19, 02:40    [21980441]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
invm
Member

Откуда: Москва
Сообщений: 9349
Соколов Валерий
Прикладываю планы выполнения.
Видимо не туда приложили.

Mind
Замените на два запроса соединенных через UNION или UNION ALL
Там и так union all посредством index intersection.
27 сен 19, 10:28    [21980585]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

Откуда:
Сообщений: 30
Планы

К сообщению приложен файл (plans.zip - 13Kb) cкачать
27 сен 19, 11:29    [21980661]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
Соколов Валерий
Планы


План одинаковые.

Для Москвы перед фильтром (1000) выбирается 1547 записей размером 13Мб.

Для Свердловска перед фильтром (1000) выбирается 310 тыс записей размером 1.5Г.
27 сен 19, 14:39    [21980942]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

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

Понимаю - это "задача" от Gerros...
Но не понимаю как с этим бороться? Уж простите начинающего... :) разъясните плиз!
27 сен 19, 20:59    [21981340]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Gerros
Member

Откуда: Харьков
Сообщений: 501
Соколов Валерий,

[новый транзит].[№ записи] - это первичный ключ? по нему индекс есть? кластерный не хотите сделать?
[новый транзит].[код плательщика] - индекс есть?
27 сен 19, 23:19    [21981407]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
PizzaPizza
Member

Откуда:
Сообщений: 370
Соколов Валерий
Но не понимаю как с этим бороться? Уж простите начинающего... :) разъясните плиз!


Экстенсивно или интенсивно можно бороться. Более мощный сервер или оптимизация и уменьшение выборки (если это вообще возможно). Другими словами - вам надо, что бы ваши физические ресурсы соответствовали вашим запросам, при условии качественной оптимизации запросов конечно же.

Для начала можно посмотреть, а надо ли вам действительно все 310 тыс записей размером 1.5Г выбирать по регулярному запросу, или можно эти записи как то пре-агрегировать например.
28 сен 19, 06:46    [21981497]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

Откуда:
Сообщений: 30
PizzaPizza
Соколов Валерий
Но не понимаю как с этим бороться? Уж простите начинающего... :) разъясните плиз!



Для начала можно посмотреть, а надо ли вам действительно все 310 тыс записей размером 1.5Г выбирать по регулярному запросу, или можно эти записи как то пре-агрегировать например.


Так а мне и не надо 310 000 - При выборке по Екатеринбургу их там столько и нет! Там всего 2 000 записей!
29 сен 19, 14:54    [21982009]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

Откуда:
Сообщений: 30
Gerros
Соколов Валерий,

[новый транзит].[№ записи] - это первичный ключ? по нему индекс есть? кластерный не хотите сделать?
[новый транзит].[код плательщика] - индекс есть?


[№ записи] - да. первичный ключ. Был некластеризованный, пересоздал. Изменений нет.
[код плательщика] - да. индекс есть.
29 сен 19, 15:22    [21982023]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
Соколов Валерий
Member

Откуда:
Сообщений: 30
PaulWist
Соколов Валерий
Планы


План одинаковые.

Для Москвы перед фильтром (1000) выбирается 1547 записей размером 13Мб.

Для Свердловска перед фильтром (1000) выбирается 310 тыс записей размером 1.5Г.


Вот мне непонятно что есть "выбирается"? Там всего записей по "Свердловску" около 2 000!
Они все подряд выгребаются? беtз учета условия "[В город]=Екатеринбург"
29 сен 19, 15:24    [21982024]     Ответить | Цитировать Сообщить модератору
 Re: Разный план выполнения  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31355
Соколов Валерий
PaulWist
пропущено...


План одинаковые.

Для Москвы перед фильтром (1000) выбирается 1547 записей размером 13Мб.

Для Свердловска перед фильтром (1000) выбирается 310 тыс записей размером 1.5Г.


Вот мне непонятно что есть "выбирается"? Там всего записей по "Свердловску" около 2 000!
Они все подряд выгребаются? без учета условия "[В город]=Екатеринбург"
Что бы найти N записей, которые удовлетворяют условиям, может понадобиться прочитать больше N записей (и, как правило, так и происходит).

Вы же рассказываете про операцию "Просмотр строк таблицы [Новый транзит]" ?
Вы же не думаете, что все 2000 записей, удовлетворяющих всем условиям запроса, находятся в начале таблицы?
А там уж как повезёт; если они в конце таблицы, то придётся просмотреть, и проверить на условия, все записи в таблице.
29 сен 19, 19:59    [21982088]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить