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

Откуда:
Сообщений: 633
Здравствуйте, всем хорошего дня

Извиняюсь за глупый вопрос

пытаюсь проанализировать план запроса и на первое на что обратил внимание в свойствах инструкции select

Причина преждевременного завершения оптимизации инструкции: Время ожидания

Вопрос: Хорошо это или плохо? Подскажите пожалуйста.
Моё мнение это скорее всего плохо. С анализами планов пока плаваю, поэтому и спрашиваю совета.
сам план выполнения приложил.

К сообщению приложен файл. Размер - 34Kb
16 авг 15, 10:06    [18024416]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
первое, что бросается в глаза - это наличие в вашем плане поиски по ключу (key lookup), а это достаточно тяжёлая операция, поэтому, для начала, постарайтесь построить покрывающие некластерные индексы для вашего запроса, например, через влюченные поля (include).

По поводу "Причина преждевременного завершения оптимизации инструкции: Время ожидания", можете ознакомиться в статье - http://www.somewheresomehow.ru/optimizer_unleashed_1/
16 авг 15, 11:20    [18024480]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
o-o
Guest
+ off

какой отличный пример "смеси французского с нижегородским"
причем на key lookup их хватило (а лучше бы нет), а на compute scalar -- нет.
16 авг 15, 12:26    [18024580]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
saley
Member

Откуда:
Сообщений: 633
спасибо за помощь,
после анализа плана выяснилось что проблема была в несоответствии типов данных в запросе,
поработал с индексами и в принципе картинка кардинально изменилась.

К сообщению приложен файл. Размер - 26Kb
16 авг 15, 14:31    [18024869]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
o-o
Guest
saley
картинка кардинально изменилась.

ну да, если сначала индексы использовались, то теперь не используются совсем.
это скорее во втором случае типы не те или вообще функции использовны.
т.е. вам посоветовали правильные индексы построить, а вы их просто исключили.
----
а изменилась у вас оценка.
во втором случае он считает, что больше строк вернет, отсюда и скан, и hash match.
а где оценка правильнее, знаете только вы, не показано же, сколько строк предполагается на выходе и сколько возвращается
----
запрос бы показали.
наверняка там юнион того, что вообще в 1 скан можно организовать
16 авг 15, 18:31    [18025330]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
gandjustas
Member

Откуда:
Сообщений: 857
Блог
saley
спасибо за помощь,
после анализа плана выяснилось что проблема была в несоответствии типов данных в запросе,
поработал с индексами и в принципе картинка кардинально изменилась.


Ты текст запроса приведи.
16 авг 15, 20:41    [18025694]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
saley
Member

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

вы правы, у меня есть union по таблице Т101 это видно на плане.
опишу структуру

созданы три таблицы Т27,Т97,Т101

В таблице Т27 создан первичный ключ id_schfact в этой таблице у меня внесена информация по документу(дата,номер,тип документа, привязка к договору и т.д)

В таблице Т97 хранится постатейная расшифровка документа из Т27 и связана с ней по внешнему ключу id_schfact
В этой таблице есть ещё привязка к определённым объектам id_subsbj, так как документ из Т27 может включать ссылку на несколько объектов сразу. Первичный ключ в этой таблице id_schitem

В таблице Т101 хранится информация для каждой строки id_schitem таблицы Т97
Смысл таблицы Т101 в том чтобы отображать движение данных по статье id_schitem и id_subsbj, где id_subsbj это переменная величина.
например
В таблице Т27 есть документ у которого
id_schfact = 20382 и id_doc = 1232
В таблице Т97 есть расшифровка статей документа
id_schfact = 20382
id_schitem ValueItem id_subsbj id_SchFact id_itempaid
32964 15000000 782509 20382 2598
32965 15000000 782509 20382 1973
32966 15000000 782509 20382 2370
32967 15000000 782509 20382 2456

в таблице Т101 для позиции 32967 указано движение
id_schitem id_subsbjIsh id_subsbDest ValueItem dateMove OtherVyb Reklas id_acountIsh id_acountDest
32967 782509 787691 24147,81 31.01.15 NULL NULL 1 1
32967 787850 787850 24036,95 31.03.15 1 NULL 1 3

что я пытаюсь решить

1. привести таблицу Т101
к виду

Т27.id_SchFact, Т27.id_doc, Т101.id_schitem, Т101.id_subsbjIsh, Т101.ValueItem, Т101.dateMove, Т101.id_acountIsh
union all
Т27.id_SchFact, Т27.id_doc, Т101.id_schitem Т101.id_subsbjDest, Т101.ValueItem, Т101.dateMove, Т101.id_acountDest

т.е. разбить Т101 на две части ISH и DEST и соединить их в одну и взять ещё исходную информацию из Т27.

Думал сделать одну общую таблицу и потом делать выборку по нужным мне полям.


что в итоге получилось, сделал View

ALTER view [dbo].[ViewT101]
AS

select
[id_schitem] =cast( a.[id_schitem] as int)
, [id_subsbj] = cast(a.[id_subsbjDest] as bigint)
, Summ = cast(a.[ValueItem] as Money)
, [Reklas] =cast(isnull(a.[Reklas],0) as smallint)
, [OtherVyb] = cast(isnull(a.[OtherVyb],0) as smallint)
, [DateGet] = cast([Datemove] as smalldatetime)
, [id_acount] = cast([id_acountDest] as int)
, id_acountIsh = cast(a.id_acountIsh as int)
, id_acountDest = cast(a.id_acountDest as int)
from
dbo.T101 a
union all
select
[id_schitem] = cast(a.[id_schitem] as int)
, [id_subsbj] = a.[id_subsbjIsh]
, Summ = cast(case
when (a.[id_subsbjIsh] != a.[id_subsbj] or ( a.[id_subsbjIsh] = a.[id_subsbj] and ISNULL(a.[ValueItem], 0) > 0) ) and [id_acountIsh] = [id_acountDest] then -1* a.[ValueItem]
when [id_acountIsh] != [id_acountDest] then -1* a.[ValueItem]
else 0
end as Money)
, [Reklas] = cast(isnull(a.[Reklas],0) as smallint)
, [OtherVyb] = cast(isnull(a.[OtherVyb],0) as smallint)
, [DateGet] = cast([Datemove] as smalldatetime)
, [id_acount] = cast([id_acountIsh] as int)
, id_acountIsh = cast(a.id_acountIsh as int)
, id_acountDest = cast(a.id_acountDest as int)
from
dbo.T101 a


и далее пытаюсь объединить с Т27 через Т97.[id_schitem] и Т97.[id_SchFact]

самый первый план в этом посте это пытался в запрос включать поля из Т97.[id_schitem] и Т97.[id_SchFact] и делать какой либо поиск по например Т97.[id_SchFact] = 20382. Сразу в плане появляются вложенные циклы. Также они появляются если я не привожу явно типы данных во ViewT101. По поводу ключей. После компиляции в плане система мне предлагала создать ключи по [id_subsbjIsh], [id_subsbjDest] и [id_schitem] которые я и создал. Вы говорите что я не использую ключи, но ведь система не требует так ради эксперимента я явно указывал ключи. Для последнего плана запрос выглядит следующим образом

select b.id_schitem, a.SummBezNDS, b.SummBezNDS, b.DateGet, c.id_SchFact, c.id_doc
from
viewT101 b
left join
T97 a with (index(IX_T97_obj))
on
isnull(a.id_schitem,0) = isnull(b.id_schitem,0)
left join
T27 c
on
isnull(c.[id_SchFact],0)= isnull(a.[id_SchFact],0)

Самое интересное сейчас пробовал добавить where c.id_SchFact = 20382 сразу появляются вложенные циклы.
План прилагаю. Очень интересно ваше мнение.

К сообщению приложен файл. Размер - 20Kb
17 авг 15, 10:44    [18027403]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
смотрю_тут
Member

Откуда:
Сообщений: 1368
вообще бы начинал с вопроса, что вас сейчас не устраивает в выполнение данного запроса и чего хотите добиться?
Скорость? Создаваемая нагрузка?
Объем данных в таблицах какой?
17 авг 15, 11:18    [18027653]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
o-o
Guest
вы зачем всюду приводите к каким-то типам,
а именно к тем же самым типам, что и так уже сеть?

ну и про where,
разумеется, если надо всего пару строк вернуть,
индекс будет использован(если совсем его не отрубить, конечно) и вложенные циклы тоже,
а когда всю таблицу, особенно здоровую, то hash join.
посмотрите сколько строк на выходе в обоих случаях, разницу видите?
17 авг 15, 11:26    [18027716]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31986
saley
select  b.id_schitem, a.SummBezNDS, b.SummBezNDS, b.DateGet, c.id_SchFact, c.id_doc  
from 
	viewT101 b 
	left join T97 a with (index(IX_T97_obj))
	     on isnull(a.id_schitem,0) =  isnull(b.id_schitem,0)
	left join T27 c
	     on isnull(c.[id_SchFact],0)= isnull(a.[id_SchFact],0)
Ужас, сплошные приведения типов и функции!
Поля id_schitem в таблицах какого типа?
Поля id_SchFact в таблицах какого типа?
isnull зачем?
17 авг 15, 11:28    [18027736]     Ответить | Цитировать Сообщить модератору
 Re: анализ плана выполнения  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31986
saley
Для последнего плана запрос выглядит следующим образом
И ещё - в запросе нет условий выборки.
Вы хотите получить все записи из ваших таблиц? Тогда да, наверное, оптимально будет сканировать.

saley
что я пытаюсь решить

1. привести таблицу Т101 к виду
Т27.id_SchFact, Т27.id_doc, Т101.id_schitem,	Т101.id_subsbjIsh, Т101.ValueItem,  Т101.dateMove, Т101.id_acountIsh
 union all
Т27.id_SchFact, Т27.id_doc, Т101.id_schitem	 Т101.id_subsbjDest, Т101.ValueItem,  Т101.dateMove,  Т101.id_acountDest
т.е. разбить Т101 на две части ISH и DEST и соединить их в одну и взять ещё исходную информацию из Т27.
В вашей вьюхе нет разбиения "на две части ISH и DEST". В каждой части union all у вас выводится вся таблица Т101, просто добавляется немножко вычислений над полями. Логика получается непонятная, для чего это всё?
17 авг 15, 11:36    [18027789]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить