Имя: Пароль:
1C
 
Простейший запрос и его трасса
0 Sasha_H
 
22.11.18
15:04
Добрый день!

1С:Предприятие 8.3 (8.3.13.1513)

Не понимаю почему платформа циклически делает кучу маленьких запросов.

ВЫБРАТЬ
    Номенклатура.ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура


https://pastenow.ru/42d23fef832175164d851e7c6e24dc3d

Записей в справочнике мало для теста прогоняю 137 записей. В трасе 137 запросов. Я ВШОКЕ как это понимать? Почему запрос не один!?
1 Sasha_H
 
22.11.18
15:04
2 Sasha_H
 
22.11.18
15:05
exec sp_executesql N'SELECT
T1._IDRRef,
T1._Description
FROM dbo._Reference269 T1
WHERE ((T1._Fld1952 = P1)) AND (T1._IDRRef = @P2)',N'P1 numeric(10),@P2 varbinary(16)',0,0x80CF005056B9DBD311E75CCFD52EC77E
3 Sasha_H
 
22.11.18
15:05
exec sp_executesql N'SELECT
T1._IDRRef,
T1._Description
FROM dbo._Reference269 T1
WHERE ((T1._Fld1952 = P1)) AND (T1._IDRRef = @P2)',N'P1 numeric(10),@P2 varbinary(16)',0,0x80CF005056B9DBD311E75CCFD52EC783
4 Sasha_H
 
22.11.18
15:05
и так далее...
5 ptiz
 
22.11.18
15:06
(0) Потому что ты это делаешь в консоли запросов и запросы генерятся, чтобы показать представление на экране.
6 Dmitry1c
 
22.11.18
15:06
а чо прикольно
7 youalex
 
22.11.18
15:06
_Description
8 Dmitry1c
 
22.11.18
15:06
(5) ловите эксперта!
9 Sasha_H
 
22.11.18
15:08
(5) Согласен
10 Sasha_H
 
22.11.18
15:09
(8) да ты что!
11 Sasha_H
 
22.11.18
15:11
(5) Точняк я жестко затупил. Спасибо!
12 МихаилМ
 
22.11.18
15:16
(11) в 1с77 точно также.
13 Sasha_H
 
22.11.18
15:21
Вопрос снят. Я реально жестко тупанул забыв, то чтобы предоставить ссылку на форме платформа делает еще запрос.
14 arsik
 
гуру
22.11.18
15:36
Вопрос почти по теме.
А есть инструмент, что бы выполнить запрос и посмотреть сразу его трассировку?
15 arsik
 
гуру
22.11.18
15:37
+(14) Типа консоль запросов с трассировкой MSSQL\PostgreSQL
16 IvanGorbunov
 
22.11.18
15:38
(14) а есть кстати для файловой базы?
17 Mankubus
 
22.11.18
15:38
(14) поищи инструменты разработчика
18 los_hooliganos
 
22.11.18
15:39
(14) Трассировки нету.
А вот вид в скуль формате есть.
Трассировка это запись данных отладки запроса.
19 arsik
 
гуру
22.11.18
15:44
(16) Для файловой такого не будет. Формат данных то закрыт.
(17) Ок. Надо будет им задонатить. Инструмент хорош.
(18) Ну и? Какая ни будь тулза включает перед запросом
, забирает данные и выключает. И что бы все автоматом. Сейчас сложно, тем более если с базой еще кто то работает.
20 youalex
 
22.11.18
17:35
(14) КИП
21 arsik
 
гуру
22.11.18
17:39
(20) Он вроде только для Корп. Ну и эту всю бодягу еще разворачивать, когда нужно пару запросов глянуть.
22 Sasha_H
 
22.11.18
17:47
И все -же я туплю. Пытаюсь разобраться с трасами при соединении.

ВЫБРАТЬ
    СвободныеОстаткиОстатки.Номенклатура КАК Номенклатура,
    СвободныеОстаткиОстатки.Склад КАК Склад,
    СвободныеОстаткиОстатки.ВНаличииОстаток КАК ВНаличииОстаток
ПОМЕСТИТЬ ВтОстатки
ИЗ
    РегистрНакопления.СвободныеОстатки.Остатки КАК СвободныеОстаткиОстатки

ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВтОстатки.ВНаличииОстаток КАК ВНаличииОстаток,
    СпрНоменклатура.Наименование КАК Наименование
ИЗ
    ВтОстатки КАК ВтОстатки
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
        ПО ВтОстатки.Номенклатура = СпрНоменклатура.Ссылка

https://pastenow.ru/46EPP

Почему при соединении справочника с ВТ возвращается количество всех его записей.?...
23 Sasha_H
 
22.11.18
17:48
24 palsergeich
 
22.11.18
17:49
(14) <plansql/ >
25 Sasha_H
 
22.11.18
17:49
В трасе видно, что возвращено 215 записей это количество всех элементов справочника. И также поиск на внутреннем соединении ВНЕ кластерном индексе, что еще более странно поскольку соединение ССЫЛКА = ССЫЛКА
26 palsergeich
 
22.11.18
17:50
(21) КИП <> КОРП
27 palsergeich
 
22.11.18
17:51
(25) У вас поле ВтОстатки.ВНаличииОстаток не входит в индекс - скорее всего это и есть причина - не полное попадание в индекс
28 palsergeich
 
22.11.18
17:52
ИНДЕКСИРОВАТЬ ПО

    Номенклатура
- в Ващей ситуации совершенно бесполезно
29 Sasha_H
 
22.11.18
17:56
(28) а я эксперементирую по разному )
30 Sasha_H
 
22.11.18
17:57
(27) Да но это временная таблица.

Тоесть, что у нас получается. Чтобы получить оптимально Наименование товара я присоединяю временную таблицу к физической (справочник.Номенклатура), а если бы в нем было 1000000 записей - это катастрофа
31 palsergeich
 
22.11.18
17:58
вы же понимаете что каждый пакет в запросе - отдельный запрос.
Если вы из пакетного запроса меняете пакет и не меняете пакет 2, то оптимизатор при исполнениии запроса 2 смотрит - есть ли такой уже скомпилированный план или нет, если есть то исполняет по нему.
И ему все равно что сейчас это уже не актуально
32 palsergeich
 
22.11.18
17:59
(30) Если у Вас будет 1000000 записей во временной таблице: то проблемы будет 2 - создвние этой таблицы и построение индекса - это не бесплатно и весьма затратно.
33 palsergeich
 
22.11.18
18:00
В тех текстах которые проводил я - на больших временных таблицах от Индексировать как правило больше вреда чем пользы
34 Sasha_H
 
22.11.18
18:14
(31) Так вопрос сейчас не об том, а о том почему он при соединении с ВТ в самой ВТ строк меньше опросил ВЕСЬ справочник номенклатуры.

Представим ситуацию на остатках 100 элементов соединение с Номенклатурой (где количество на справочнике сотни тысяч) он прочитает весь его!
35 palsergeich
 
22.11.18
18:19
(34) а какой был физический оператор?
36 palsergeich
 
22.11.18
18:19
Если clustered index seek то все хорошо
37 palsergeich
 
22.11.18
18:21
Так же обрати внимание на количество чтений.
+ При изменении запроса в пакетном запросе рекомендую в тесте скидывать кеш планов запроса
38 Sserj
 
22.11.18
18:22
(34) Потому что у SQL сервера нет статистики по временной таблице и он не знает что в ней будет меньше строк. Ее не надо индексировать тогда будет использован индекс справочника.
39 palsergeich
 
22.11.18
18:23
(34) оптимизатор тоже штука умная, план запроса на 200 элементах справочника от плана запросов при 1 000 000 элементов может отличаться.
Тут как оптимизатор решит
40 Sasha_H
 
22.11.18
18:25
(39) Это да!
41 palsergeich
 
22.11.18
18:26
(38) увы но нет, каждый запрос в пакете - физически отдельный запрос.
И на момент выполнения запроса 2 оптимизатор уже знает сколько строк в таблице 1.
Это в общем то и было киллер фичей пакетных запросов относительно вложенных запросов.
Другое дело что план на 1 запись и на 1 миллион будет одинаков.
На тесте чистите кеш планов запросов что бы видеть актуальные планы.
42 Sasha_H
 
22.11.18
18:26
(38) Брехня - удалил индекс фигня таже
43 Sasha_H
 
22.11.18
18:27
Насчет индекса в ВТ - если его не будет то таблица будет сканироваться и кстати я не соглашусь с  palsergeich в индексе есть смысл и об этом говорится на курсах Бурмистрова Андрея
44 Вафель
 
22.11.18
18:27
а какой джойн там испльзуется?
45 Sasha_H
 
22.11.18
18:28
/Да я согласен с  palsergeich , что на больших объема накладные расходы но и выгришь там существен чем Сканирование
46 Sasha_H
 
22.11.18
18:28
(44) пробовал и Левое и Внутреннее
47 Вафель
 
22.11.18
18:28
(43) индекс по временно? он нужен если она используется более 1 раза
48 Вафель
 
22.11.18
18:28
(46) имеется ввиду: merge - hash - lookup
49 Sasha_H
 
22.11.18
18:29
(47) Совершенно верно данный пример это лишь часть ОДНОГО большого запроса. Это эксперимент просто и я в разрыве шаблона сейчас
50 Sasha_H
 
22.11.18
18:31
51 H A D G E H O G s
 
22.11.18
19:13
(50) Оптимизатор решил, что так эффективнее.

Там внутри, платформа накладывает условие на область данных ( у вас это поле _Fld1551, при этом не учитывая, что почти все записи номенклатуры принадлежат этому полю (возможно нужно обновить статистику).

Если вы уменьшите первую выборку, например
ВЫБРАТЬ ПЕРВЫЕ 10

    СвободныеОстаткиОстатки.Номенклатура КАК Номенклатура,

И осложните посмтроение хэштаблицы, убрав Сортировку выборки

убрав:
ИНДЕКСИРОВАТЬ ПО

    Номенклатура


возможно вы получите поиск по кластерному индексу справочника в цикле.
52 palsergeich
 
22.11.18
19:26
(51) +1
(50) На Вашем месте я не искал бы ведьм там где их скорее всего нет, конкретно эти запросы очень простые и вероятность того, что оптимизатор круто ошибся крайне мала.
К сожалению мой пост, который я набирал в метро так и не отправился, а заново набирать лень.
53 H A D G E H O G s
 
22.11.18
19:38
(52) Ну вообще, оптимизатор там лажает прям конкретно
54 palsergeich
 
22.11.18
19:40
(53) Я просто сам файл не смотрел - на мобиле не удобно.
Заставил старика смотреть))).
55 H A D G E H O G s
 
22.11.18
19:41
И проще всего его победить - добавить в выборку 2 запроса легкое поле, не входящее в индексы, например

СпрНоменклатура.ВестиУчетПоГТД КАК ВестиУчетПоГТД
56 Sasha_H
 
22.11.18
19:47
Тут интерес просто возник, какого ИКС... Со статистикой все гуд поскольку обновил вручную специально но так и ничего не поменялось.

Конечно данных мало. И возник логичных панический вопрос, черт , а если он ошибается так на больших объемах то это БЕДА.

Ведь у меня какая задача. Я хочу в отчет чтобы сократить вывод циклических запросов Номенклатура.Ссылка соответсвенно получить Наименование. Если сделать как рекомендует 1С ПРЕДСТАВЛЕНИЕ(Ссылка) то тут лажа - там вообще происходит поиск в ключе, что не гуд.

А если сделать ВТ.Номенклатура.наименование то оптимизатор тяжело работает. Вот я и начал искать ведьм!
57 Sasha_H
 
22.11.18
19:49
Черт побери как лучше!?
58 H A D G E H O G s
 
22.11.18
19:51
(57) Добавь в выборку СпрНоменклатура.ВестиУчетПоГТД
59 Sasha_H
 
22.11.18
19:55
Вытащил артикул. Но как бы ничего не поменялось на дропе обновил план
60 Sasha_H
 
22.11.18
20:05
И все же ведьмы есть и на лицо. Запустил этот отчет на боевой.

Rows         Executes     StmtText                                                                                                                                                                                                                             StmtId       NodeId       Parent       PhysicalOp   LogicalOp    Argument                                                                                                                                                                                                     DefinedValues                                EstimateRows EstimateIO   EstimateCPU  AvgRowSize   TotalSubtreeCost OutputList                                   Warnings     Type         Parallel     EstimateExecutions
----         --------     --------                                                                                                                                                                                                                             ------       ------       ------       ----------   ---------    --------                                                                                                                                                                                                     -------------                                ------------ ----------   -----------  ----------   ---------------- ----------                                   --------     ----         --------     ------------------
21388        1            Hash Match(Inner Join, HASH:([T1].[_Q_000_F_000RRef])=([T2].[_IDRRef]), RESIDUAL:([erp_UT_Robinzon_HotCopy].[dbo].[_Reference169].[_IDRRef] as [T2].[_IDRRef]=[tempdb].[dbo].[#tt26].[_Q_000_F_000RRef] as [T1].[_Q_000_F_000RRef])) 0            0                         Hash Match   Inner Join   HASH:([T1].[_Q_000_F_000RRef])=([T2].[_IDRRef]), RESIDUAL:([erp_UT_Robinzon_HotCopy].[dbo].[_Reference169].[_IDRRef] as [T2].[_IDRRef]=[tempdb].[dbo].[#tt26].[_Q_000_F_000RRef] as [T1].[_Q_000_F_000RRef])                                              21152,9      0            0,851722     124          1,22791          [T1].[_Q_000_F_001], [T2].[_Description]                  PLAN_ROW     0            1                  
21388        1              |--Table Scan(OBJECT:([tempdb].[dbo].[#tt26] AS [T1]))                                                                                                                                                                             0            1            0            Table Scan   Table Scan   OBJECT:([tempdb].[dbo].[#tt26] AS [T1])                                                                                                                                                                      [T1].[_Q_000_F_000RRef], [T1].[_Q_000_F_001] 21388        0,0771991    0,0236838    36           0,100883         [T1].[_Q_000_F_000RRef], [T1].[_Q_000_F_001]              PLAN_ROW     0            1                  
25746        1              |--Index Seek(OBJECT:([erp_UT_Robinzon_HotCopy].[dbo].[_Reference169].[_Reference169_Descr] AS [T2]), SEEK:([T2].[_Fld970]=[@P1]) ORDERED FORWARD)                                                                                 0            2            0            Index Seek   Index Seek   OBJECT:([erp_UT_Robinzon_HotCopy].[dbo].[_Reference169].[_Reference169_Descr] AS [T2]), SEEK:([T2].[_Fld970]=[@P1]) ORDERED FORWARD                                                                          [T2].[_IDRRef], [T2].[_Description]          25746        0,246829     0,0284776    127          0,275306         [T2].[_IDRRef], [T2].[_Description]                       PLAN_ROW     0            1
61 Sasha_H
 
22.11.18
20:07
О фак ))

ввобщем записей на остатках 21388

а это

25746 Кво на справочнике номенклатуры. Тоесть чтобы получить наименование он один Х...рен смотрит весь справочник - Я В ШОКЕ
62 H A D G E H O G s
 
22.11.18
20:13
(59) Ты чето не то сделал.
63 H A D G E H O G s
 
22.11.18
20:15
ВЫБРАТЬ
    СвободныеОстаткиОстатки.Номенклатура КАК Номенклатура,
    СвободныеОстаткиОстатки.Склад КАК Склад,
    СвободныеОстаткиОстатки.ВНаличииОстаток КАК ВНаличииОстаток
ПОМЕСТИТЬ ВтОстатки
ИЗ
    РегистрНакопления.СвободныеОстатки.Остатки КАК СвободныеОстаткиОстатки
;



////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ
    ВтОстатки.ВНаличииОстаток КАК ВНаличииОстаток,
    СпрНоменклатура.Наименование КАК Наименование,
    СпрНоменклатура.ВестиПоГТД КАК ВестиПоГТД

ИЗ
    ВтОстатки КАК ВтОстатки
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
        ПО ВтОстатки.Номенклатура = СпрНоменклатура.Ссылка

Вот так сделай.
Вытащи поле, которое не индексировано.
64 palsergeich
 
22.11.18
20:17
(63) так он получит то, от чего бежал. (56)
65 Sasha_H
 
22.11.18
20:20
Да один хер только в профиль обновил план уже на боевых реалиях.
66 Sasha_H
 
22.11.18
20:21
Не понимаю почему просматривается ВСЯ ТАБЛИЦА СПРАВОЧНИКА %)
67 Evg-lylyk
 
22.11.18
20:22
(15) http://catalog.mista.ru/public/940250/
Постгрес не поддерживает
68 Evg-lylyk
 
22.11.18
20:24
(16) для файловой работает
69 Sasha_H
 
22.11.18
20:24
Самое смешное, что СЕРВЕРА вообще разные. СКЛ версии абсолютно разные только платформа 1с одна и та же. А цука план запроса 1 в 1
70 H A D G E H O G s
 
22.11.18
20:28
(66) Так это нормально.
71 H A D G E H O G s
 
22.11.18
20:33
(66) Из ненормального там - фанатичное использование некластерного индекса вместо кластерного, но, возможно, чтение кластерного индекса затратнее.
72 H A D G E H O G s
 
22.11.18
20:34
Ну и HashJoin вместо MergeJoin, хоть таблицы и сравнимы по размерам.
73 Sasha_H
 
22.11.18
20:38
(70) У меня клиника по ходу. Но разве не должно быть просмотрено ровно то количество записей которое в ВТ. ??
74 Sasha_H
 
22.11.18
20:45
ВЫБРАТЬ ПЕРВЫЕ 10
    СпрНоменклатура.Ссылка КАК Ссылка,
    0 КАК Поле1
ПОМЕСТИТЬ Товары
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Товары.Поле1 КАК Поле1,
    СпрНоменклатура.Наименование КАК Наименование
ИЗ
    Товары КАК Товары
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
        ПО Товары.Ссылка = СпрНоменклатура.Ссылка

А вот так запрос в эфективном плане как и положено просмотрел 10 записей.
75 Sasha_H
 
22.11.18
20:45
Ребят так что не так-то? ... Это я идиот так и скажите !
76 palsergeich
 
22.11.18
20:47
(73) Давай начем сначала:
Что ты имеешь ввиду над просмотрено ровно то количество записей которое в ВТ.
77 palsergeich
 
22.11.18
20:48
Мне кажется у тебя в голове немножко каша
78 palsergeich
 
22.11.18
20:48
Это нормально
79 Sasha_H
 
22.11.18
20:55
Посмотри план запроса который только что представил. Тоесть в ВТ 10 записей товаров.

Инерджойном я соединяю ВТ = Справочник.Номенклатура и тут все шикарно он как положено Вернул 10 записей не 122 как до этого всех элементов в справочнике и смотрел кластерный индекс все как положено.

А из примера, что с по остаткам. Я получаю ВТ без склада по товарам тоесть 100 элементов в выборке ВТ. и там план запроса смотрит весь справочник все его элементы и не кластерный индекс.

В чем у меня каша?
80 Sasha_H
 
22.11.18
20:58
Черт точно таки каша... все пойду утоплюсь

Сделал выбрать первые 133 и опять он стал просматривать всю таблицу справочника
81 palsergeich
 
22.11.18
20:58
(79) Ну терминология так себе - я ее за день наслушался.
Понимает, умеет и тд.
82 palsergeich
 
22.11.18
20:59
(80) Конечно, Первые - всегда скан
83 Sasha_H
 
22.11.18
21:00
(81) здесь не совсем понял.
84 Sasha_H
 
22.11.18
21:01
(82) А ты план запроса смотрел тектовый? А то как еще расказать я не понимаю
85 palsergeich
 
22.11.18
21:02
(83) Ключевое слово ПЕРВЫЕ - приводит к сканированию
86 palsergeich
 
22.11.18
21:05
(84) Мне лень тебе искать мануалы
1.2.    Операция Scan всегда означает полный (а не частичный) просмотр всей таблицы или индекса, единственное исключение это когда в запросе есть ключевые слова ВЫБРАТЬ ПЕРВЫЕ тогда скан будет не всей таблицы/индекса, а только первых записей. Частичный скан в плане запроса будет выглядеть как оператор Seek но с условием Where, в графическом плане появится раздел Predicate.
87 Sasha_H
 
22.11.18
21:05
(85) ни к чему не приводит. Опять выполнил этот запрос и опять Rows 215 Хотя есть на дропе план с инеальным попаданием. НИКТО не работает данные не обнновляются.
88 palsergeich
 
22.11.18
21:06
(87) Слишком сложно.
Я отработал 8 часов.
Я не могу стелепатировать про какой запрос ты говоришь и какой там план.
89 Sasha_H
 
22.11.18
21:07
Rows         Executes     StmtText

10           1            Nested Loops(Inner Join, OUTER REFERENCES:([T1].[_Q_001_F_000RRef]))

10           1              |--Table Scan(OBJECT:([tempdb].[dbo].[#tt18] AS [T1]))

10           10             |--Clustered Index Seek(OBJECT:([UT].[dbo].[_Reference215].[_Reference215HPK] AS [T2]), SEEK:([T2].[_Fld1551]=[@P1] AND [T2].[_IDRRef]=[tempdb].[dbo].[#tt18].[_Q_001_F_000RRef] as [T1].[_Q_001_F_000RRef]) ORDERED FORWARD) 0            2            0            Clustered Index Seek Clustered Index Seek OBJECT:([UT].[dbo].[_Reference215].[_Reference215HPK] AS [T2]), SEEK:([T2].[_Fld1551]=[@P1] AND [T2].[_IDRRef]=[tempdb].[dbo].[#tt18].[_Q_001_F_000RRef] as [T1].[_Q_001_F_000RRef]) ORDERED FORWARD [T2].[_Description]
90 Sasha_H
 
22.11.18
21:08
Вот идеальный план в кластерном индексе по запросу Где Выбрать первые 10. Но я сейчас его выполняю опять И Rows 215, а это к-во элементов в справочнике ВСЕГО
91 palsergeich
 
22.11.18
21:10
(90) Где б..ть rows 215?
там 3 оператора.
Еще раз повторю - хочешь услышать ответ, будь добр текст план и что не нравится укажи.
Не ну серьезно, ты сидишь с кучей открытых окон, а я должен угадать?(
92 Sasha_H
 
22.11.18
21:10
Щас все будет,
93 palsergeich
 
22.11.18
21:14
Сорри если что, день тяжелый был.
Помочь то хочется
94 Sasha_H
 
22.11.18
21:19
Вот к этим запросам вопроса нет. НО хочу подчеркнуть, что этот план менялся. Сейчас тут ВЫБРАТь ПЕРВЫЕ 200 для ВТ и ВТ соединяется с номенклатурой и как видно из плана Rows на уровне Номенклатуры поиска 200. Но этот же запрос даже когда было выбрать первые 10 Выдавало Rows на уровне Номенклатуры 215 тоесть смотрелся ВЕСЬ справочник.

https://ibb.co/bwHGnA
https://ibb.co/i64J0V

Теперь к Запросу когда в ВТ помещается товары по остаткам. 122 элемента помещаются в ВТ но тут видно, что просматривается все 215 строк на уровне номенклатуры.

https://ibb.co/cBet0V
https://ibb.co/b0RvEq
95 palsergeich
 
22.11.18
21:25
(94) Вот теперь другое дело!
А вот смеха ради -
https://ibb.co/cBet0V
https://ibb.co/b0RvEq
В первом пакете отсортируй по номенклатуре
96 palsergeich
 
22.11.18
21:27
(94) Он почему что считает что некластерный индекс Ссылка Наименование - будет быстрее чем кластерный
97 H A D G E H O G s
 
22.11.18
21:28
(94) "что просматривается все 215 строк на уровне номенклатуры. "
Естественно.
98 palsergeich
 
22.11.18
21:29
(96) И быстрее чем 122 дергать кластерный индекс через NestedLoops
(97) Поправь, если я не прав
99 H A D G E H O G s
 
22.11.18
21:30
(94)
Давай я расшифрую.
1) Для временной таблицы построим хештаблицу.
2) Для справочника Номенклатуры найдем по индексу строки, в которых ОбластьДанных=0 и для каждой строки результата найдем строку в хэштаблице.
100 H A D G E H O G s
 
22.11.18
21:30
(98) Да, это быстрее, чем дергать 122 раза кластерный.
101 palsergeich
 
22.11.18
21:31
(100) Спасибо, а то уже я думал что у меня мазги разжижились)
102 H A D G E H O G s
 
22.11.18
21:33
Я долго не мог понять почему не MergeJoin, даже если мы помогаем SQL, сортируя 1 таблицу через Индексировать.
Но, если исходить из того, что чтение некластерного индекса выгоднее чем чтение кластерного - то и получается, что HashJoin, так как MergeJoin не возможен для результата поиска по индексу без tablespool (надо сохранить результат поиска по индексу в временной таблице), а hashjoin возможен без временного хранения.
103 H A D G E H O G s
 
22.11.18
21:35
Но если мы добавим в 2 выборку поле, не входящее ни в один из индексов - оптимизатор решит использовать кластерный индекс и будет MergeJoin при большой 1 выборке и nested loop при маленькой .
104 palsergeich
 
22.11.18
21:36
(102) (103) Успокоил, спасибо
105 H A D G E H O G s
 
22.11.18
21:38
Самое забавное будет при выборке
ВЫБРАТЬ
    Товары.Поле1 КАК Поле1,
СпрНоменклатура.Код КАК Код ,
    СпрНоменклатура.Наименование КАК Наименование

SQL настолько уверен в калечности кластерного индекса, что будет использовать выборку из 2 некластерных индексов - Индекса по коду и Индекса по наименованию.
106 palsergeich
 
22.11.18
21:39
(105) ГГГГГГ, такого еще не видел)
107 H A D G E H O G s
 
22.11.18
21:44
Hash Match(Inner Join, HASH:([T1].[_Q_001_F_000RRef])=([T2].[_IDRRef]), RESIDUAL:([Elida].[dbo].[_Reference185].[_IDRRef] as [T2].[_IDRRef]=[tempdb].[dbo].[#tt1].[_Q_001_F_000RRef] as [T1].[_Q_001_F_000RRef]))                                                                                                                                                
  |--Table Scan(OBJECT:([tempdb].[dbo].[#tt1] AS [T1]))                                                                                                                                                                                                                                                                                                          
  |--Merge Join(Inner Join, MERGE:([T2].[_Fld931], [T2].[_IDRRef])=([T2].[_Fld931], [T2].[_IDRRef]), RESIDUAL:([Elida].[dbo].[_Reference185].[_Fld931] as [T2].[_Fld931] = [Elida].[dbo].[_Reference185].[_Fld931] as [T2].[_Fld931] AND [Elida].[dbo].[_Reference185].[_IDRRef] as [T2].[_IDRRef] = [Elida].[dbo].[_Reference185].[_IDRRef] as [T2].[_IDRRef]))
                                                                                                                  
       |--Sort(ORDER BY:([T2].[_IDRRef] ASC))                                                                                                                                                                                                                                                                                                              
            |--Index Seek(OBJECT:([Elida].[dbo].[_Reference185].[_Reference185_Code] AS [T2]), SEEK:([T2].[_Fld931]=[@P1]) ORDERED FORWARD)                                                                                                                                                                                                                
       |--Sort(ORDER BY:([T2].[_IDRRef] ASC))                                                                                                                                                                                                                                                                                                                    
            |--Index Seek(OBJECT:([Elida].[dbo].[_Reference185].[_Reference185_Descr] AS [T2]), SEEK:([T2].[_Fld931]=[@P1]) ORDERED FORWARD)
108 palsergeich
 
22.11.18
21:46
(107) Спасибо за пример, покажу молодежи.
109 H A D G E H O G s
 
22.11.18
21:50
Надо почитать про цену выборки из кластерного и некластерного.

Но простейший запрос вида
ВЫБРАТЬ
    Номенклатура.Наименование КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура

всегда вызывал дефакто чтение, деюре поиск в некластерном индексе.

Чтение/поиск - потому что

SELECT
T1._Description
FROM dbo._Reference185 T1
WHERE (T1._Fld931 = P1)


WHERE (T1._Fld931 = P1) - деюре мы ищем,дефакто - находим все записи.
110 Sasha_H
 
22.11.18
22:08
Правда не понимаю с чего ты решил, что кластерный идекс калечный :)
111 H A D G E H O G s
 
22.11.18
22:10
(110) Это SQL решает, что он калечный.
112 palsergeich
 
22.11.18
22:13
Ладно, всем поки)
113 Sasha_H
 
22.11.18
22:13
да это странно почему он не взял данные с кластерного индекса они ведь лежат на верхнем уровне
114 palsergeich
 
22.11.18
22:14
(113) Потому что алгоритмы посчитали по другому
115 palsergeich
 
22.11.18
22:15
(113) Он посчитал что обратиться к некластерному индексу Наисменование Ссылка 1 раз с хешированием выгоднее чем 122 раза к кластерному
116 palsergeich
 
22.11.18
22:18
117 H A D G E H O G s
 
22.11.18
22:19
(113) Наверное причина в том, что ему нужно прочитать все колонки таблицы (их дофига у номенклатуры) при чтении кластерного индекса, а при чтении некластерного - только 3 колонки.
118 palsergeich
 
22.11.18
22:20
https://docs.microsoft.com/ru-ru/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described?view=sql-server-2017
А это предложение - вся суть:
Оптимизатор запросов обычно выбирает наиболее эффективный метод при выполнении запросов.
119 palsergeich
 
22.11.18
22:21
(117)
Вот тут кстати намек на это
В основном поиск по индексу протекает намного быстрее, чем поиск по таблице, так как в отличие от таблицы индекс часто содержит мало столбцов в каждой строке и строки расположены в отсортированном порядке.
120 palsergeich
 
22.11.18
22:22
В части мало столбцов
121 palsergeich
 
22.11.18
22:22
Если это было бы не важно, скорее всего это не упомянули бы
122 H A D G E H O G s
 
22.11.18
22:24
(119) Я думаю, сайту в (118) можно доверять.
123 H A D G E H O G s
 
22.11.18
22:24
Моя вера в SQL возвращается.
124 palsergeich
 
22.11.18
22:24
Ибо то. что говорят в мире 1с - строки расположены в отсортированном порядке - называют основным.
125 palsergeich
 
22.11.18
22:25
Но скорее всего они не договаривают)
126 palsergeich
 
22.11.18
22:26
(122) Я тоже так думаю)
127 H A D G E H O G s
 
22.11.18
22:30
За последние 2 недели я в очевидных, незначительных, тривиальных запросах, которые ты никогда не посмотришь под микроскопом, нашел подводных камней больше чем за последний год.
128 palsergeich
 
22.11.18
22:38
(113) Большое спасибо Вам за пример.
Приношу извинение за грубость, просто устал.
(127) Вам тоже спасибо.
Всем пока, до завтра)
129 Sasha_H
 
22.11.18
22:44
А вот что по этому поводу говорит Вьейра

https://ibb.co/cHaKPq
https://ibb.co/dHYjqV
130 Sasha_H
 
22.11.18
22:54
Всем огромное спасибо!
(128)
Если что я тут практически всегда. Скайп oleksandr.homyak
131 palsergeich
 
22.11.18
22:55
(129) Но тут всего лишь описано что это такое.
Это есть и тут (116)
Меня лично больше взволновала эти фраза:
так как в отличие от таблицы индекс часто содержит мало столбцов в каждой строке и строки расположены в отсортированном порядке
Кластерный индекс содержит столько же полей как и таблица.
мало столбцов в каждой строке - вот эта вроде бы незначительная фраза, но она очень много что объясняет.
132 palsergeich
 
22.11.18
22:57
Зная что просто так в документацию словосочетания не добавляют, можно сделать вывод что это дейсвтительно важно в тех или иных алгоритмах.
Даже вот это (105) поведение становится менее алогичным
133 palsergeich
 
22.11.18
22:58
Все во  теперь точно ушел
134 Sasha_H
 
22.11.18
22:58
(132) вот-вот. Я и говорю разрыв шаблона на простейших запросах
135 los_hooliganos
 
23.11.18
05:32
Лучше бы взяли и один раз прочитали "Реализация и обслуживание MS SQL" там все разжевано для уровня чайников.
136 H A D G E H O G s
 
23.11.18
12:15
(135) Даю 100%, что когда ты почитаешь вот это вот то, что ты там рекомендуешь - ты потрясешь гривой, что да, мол, все понятно и забудешь на следующий день. Если ты дойдешь до этих выводов сам, расследуя ситуацию - ты запомнишь до конца жизни. Именно поэтому я не читают rtfm до последней возможности.
137 Sasha_H
 
23.11.18
15:33
(136) абсолютно согласен. У меня и курсы Бурмистрова есть. Все понятно казалось бы. Но это все примеры из книжки. Самому разобрать это совершенно другое.

(135) но лишней литературы не бывает. взял на заметку.
138 GANR
 
23.11.18
16:20
(0) Для интереса сделайте на СКД и повторите проверку.