Имя: Пароль:
1C
1С v8
Вопрос по скорости выполнения запроса
,
0 IVT_2009
 
21.02.19
11:31
Есть такой простой запрос:

ВЫБРАТЬ
    расходнаяНакладнаятовары.Ссылка КАК Ссылка,
    расходнаяНакладнаятовары.НомерСтроки КАК НомерСтроки,
    расходнаяНакладнаятовары.нппПоТТН КАК нппПоТТН,
    расходнаяНакладнаятовары.товар.кодАпЕГАИС КАК кодАпЕГАИС,
    расходнаяНакладнаятовары.товар КАК товар,
    расходнаяНакладнаятовары.количество КАК количество,
    расходнаяНакладнаятовары.цена КАК цена,
    расходнаяНакладнаятовары.сумма КАК сумма,
    расходнаяНакладнаятовары.идСправкаА КАК идСправкаА,
    расходнаяНакладнаятовары.идСправкаБ КАК идСправкаБ,
    расходнаяНакладнаятовары.товар.полнНаименование КАК товарполнНаименование,
    расходнаяНакладнаятовары.товар.производитель КАК товарпроизводитель,
    расходнаяНакладнаятовары.товар.импортер КАК товаримпортер,
    расходнаяНакладнаятовары.Ссылка.WBRegId КАК WBRegId

ИЗ
    Документ.расходнаяНакладная.товары КАК расходнаяНакладнаятовары
ГДЕ
    расходнаяНакладнаятовары.Ссылка.WBRegId = &WBRegId


выполняется примерно 5 секунд

убираем из него

расходнаяНакладнаятовары.товар.полнНаименование КАК товарполнНаименование,
    расходнаяНакладнаятовары.товар.производитель КАК товарпроизводитель,
    расходнаяНакладнаятовары.товар.импортер КАК товаримпортер,

выполняется 0,5 сек. Другими словами обращение к полю справочника товар тормозит запрос на порядок.
Документов несколько десятков тысяч , товара то же десятки тысяч. База файловая.
Как это объяснить ?
1 JeHer
 
21.02.19
11:33
А если убрать только расходнаяНакладнаятовары.товар.полнНаименование КАК товарполнНаименование, ?
2 IVT_2009
 
21.02.19
11:34
Любое обращение к реквизитам справочника Товар через точку тормозит запрос.
3 Cyberhawk
 
21.02.19
11:35
Что тебя удивляет? В профайлере глянь и увидишь, что это левые соединения к таблице товаров делаются, а из нее - к таблицам производителей, импортеров и т.д.
4 Жан Пердежон
 
21.02.19
11:36
какой тип у реквизита "Товар"?
5 Кир Пластелинин
 
21.02.19
11:36
дык обращения "через точку". чему удивляться то?)
6 azernot
 
21.02.19
11:39
Я приведу такой пример, условный конечно.

РН - это шкаф
Строки ТЧ - это полки в шкафу
Товар - это книги в шкафу
ПолнНаименование - это содержимое первой страницы книги.

Что проще, найти нужный шкаф, перебрать полки, считать ГУИД книги с корешка, или заглянуть в каждую первую страницу книги и считать её содержимое?

Вы ещё добавьте
расходнаяНакладнаятовары.товар.производитель.ИНН
и ещё больше удивитесь.
7 IVT_2009
 
21.02.19
11:44
Как получается правильно? Выгрузить выборку в таблицу и отобрать соединением из справочника реквизиты ?
8 D_E_S_131
 
21.02.19
11:50
(7) Да без разницы. тебе нужны "дополнительные" данные, а их связать с "основными" данными ты можешь только соединением, а соединение приводит к более длительному запросу. Можешь попробовать явно соединить таблицу справочника "Номенклатура" с таблицей документа "Товары" через "Товар=Ссылка" и получайте "ПолнНаименование", "Производителя" и "Импортера" из "Номенклатуры".
9 DrWatson
 
21.02.19
11:59
(0) Попробуй индексировать поле Товар в табличной части. Плюс ещё можно продублировать WBRegId в табличной части, чтобы не было соединений с документом.
10 cons24
 
21.02.19
12:03
1) выбрать все ссылки в ВТ
2) для ссылок из вт получить данные ТЧ, поместить в ВТ, индексировать по полям, которые будут в соединении со следующей
3) соединение с Спр.Номенклатура для получения доп.данных
11 singlych
 
21.02.19
12:04
(8) А это вопрос. Вот оптимизатор соединение с товарами сделает до отбора доков по WBRegId или после?
12 D_E_S_131
 
21.02.19
12:12
(11) После сделает. Для эксперимента ТС может попробовать выбрать данные из ТЧ документа во временную таблицу, проиндексировать поле "Товар" и вторым пакетом уже выбрать окончательные данные.
13 unregistered
 
21.02.19
12:52
(0) А поле Товар у вас случайно не составного типа?
Если вдруг (мало ли) составного, то пропишите левое соединение вручную или используйте оператор ВЫРАЗИТЬ().
14 Cyberhawk
 
21.02.19
13:43
(11) (12) Иногда делает до, иногда после. Полагаться на него нельзя.
Выход по большому счету один: нужно сначала отфильтровать основную таблицу и уже потом делать левое соединение. В разных запросах. Поэтому первый в ВТ.
15 singlych
 
21.02.19
13:53
(14) Вот че-то кажется, что явное соединение не поможет, в отличие от "сначала отфильтровать основную таблицу".
16 palsergeich
 
21.02.19
13:54
А там ещё и основное условие по документам.ссылка.реквизит тоже доработать можно)
17 palsergeich
 
21.02.19
13:55
И может так оказаться, что после этого ваще огонь будет
18 singlych
 
21.02.19
13:57
(17) ну кстати да, может он тогда и сообразит сначала отобрать по условию.
19 VladZ
 
21.02.19
13:58
(0) Компания 1С своими механизмами запроса вида " расходнаяНакладнаятовары.товар.кодАпЕГАИС КАК кодАпЕГАИС" разбаловало программистов.

Нужно было делать "как в SQL": выбрал поля из таблицы. Нужны доп.поля - джоинишь нужные таблицы и выбираешь нужные поля. И тогда вопросов, как в (0), возникать не будет.
20 palsergeich
 
21.02.19
13:59
расходнаяНакладнаятовары.Ссылка.WBRegId = &WBRegId
Я про это, чисто мысленным экспериментом, если заменить это условие на массив ссылок то может быть сразу хорошо или найти такие документы пакетом ранее.
21 Cyberhawk
 
21.02.19
14:02
(15) А что за "явное соединение", на которое возлагается надежда?
22 singlych
 
21.02.19
14:03
Я бы все-таки попробовал сначала сделать типа

ИЗ
    Документ.расходнаяНакладная КАК расходнаяНакладная
    левое Документ.расходнаяНакладная.товары КАК расходнаяНакладнаятовары  по ссылка
ГДЕ
    расходнаяНакладная.WBRegId = &WBRegId

Вдруг прокатит. На ВТ тоже ресурсы требуются, тем более файловая.
23 singlych
 
21.02.19
14:04
(21) ну типа "левое соединение Номенклатура по расходнаяНакладнаятовары.товар = Номенклатура.ссылка" и вместо "расходнаяНакладнаятовары.товар.кодАпЕГАИС" писать "номенклатура.кодАпЕГАИС"
24 palsergeich
 
21.02.19
14:07
(22) плохо.
Надо делать не левое, а внутреннее и условие не в где, а в условие соединения
25 palsergeich
 
21.02.19
14:08
Вт из ссылкой много места не сожрёт, даже в файловой
26 singlych
 
21.02.19
14:12
(24) Зачем в условие соединения? Идея как раз в том, чтобы отобрать левую таблицу, а потом соединять. Хотя возможно, разницы не будет.
27 palsergeich
 
21.02.19
14:15
(26) разница есть и большая.
Попробуй на досуге.
28 Cyberhawk
 
21.02.19
14:16
(24) Наглядность запроса падает в случае переделки левого на внутреннее, куда в условия добавлен еще и фильтр-условие на "основную" таблицу.
Я бы выбрал вариант с ВТ, где отбирается основная таблица, а во втором запросе уже делается левое.
29 palsergeich
 
21.02.19
14:16
(26) только на уровне SQL работает по другому.
Упрощённо ты сначала соединить и получишь много записей, потом наложится фильтр и останется мало записей.
30 palsergeich
 
21.02.19
14:17
(28) что простите? Соединение с условием уже нечитаемо? Не знал
31 DrWatson
 
21.02.19
14:18
Что-то мне кажется, что Вы пытаетесь подходы к оптимизации SQL запросов применить к файловой базе.
Например, то же условие в ГДЕ. Оптимизатор SQL его применит до соединения, а вот файловая вряд ли.
32 Cyberhawk
 
21.02.19
14:19
(30) Не путай "наглядность падает" и "не читаемо". Что-то ты подменяешь понятия.
Когда вижу в запросе левое соединение, то мозг воспринимает это как то, что в запросе (до секции ГДЕ) будут как минимум все строки основной таблицы.
Внутренее соединение тяжелее для восприятия.
Никто не говорил, что что-то там "нечитаемо".
33 palsergeich
 
21.02.19
14:19
(31) серверная тоже далеко не факт что до.
34 palsergeich
 
21.02.19
14:20
(32) ну хз, я такую точку зрения в первый раз слышу.
Я воспринимаю внутреннее как пересечение множество.
Дело хозяйское
35 Cyberhawk
 
21.02.19
14:21
(34) Высоко паришь)
Для большинства читателей запросов попробуй добавь в условия соединения такое условие, где нет полей из обеих таблиц, они уже начнут тяму долго напрягать, а шо это такое означает.
36 palsergeich
 
21.02.19
14:25
Ну то что с ВТ проще для понимания не могу не согласиться.
Но не всегда бытрее.
37 singlych
 
21.02.19
14:33
(29)(31) Как раз интерес в том, чтобы проверить, сможет ли файловая. Так-то проще сделать как (14) и не узнать ничего про файловый оптимизатор.
38 Cyberhawk
 
21.02.19
14:36
(37) Ну узнаешь ты, допустим, что в файловой в твоем случае фильтр из ГДЕ не наложился на основную таблицу до собственно выполнения левого соединения. Или узнаешь, что наложился.
Какой видишь толк в получении такого знания?
39 singlych
 
21.02.19
14:41
(38) Узнаю отличия файловой от серверной. Буду писать аккуратнее :)
40 palsergeich
 
21.02.19
14:49
(39) скажу так: пакетный запрос в тексте ДС на файловой базе работает очень здорово.
На будущее.
41 D_E_S_131
 
21.02.19
15:22
MS SQL видимо с начала сам понимает, что нужно найти документ, а только потом соединять с Номенклатурой
https://hkar.ru/XnI5
42 H A D G E H O G s
 
21.02.19
15:24
(41) Ну дичь же
43 bolobol
 
21.02.19
15:25
(42) С чего вдруг как-то по-иному должно быть?
44 H A D G E H O G s
 
21.02.19
15:26
(43) Вот так
http://prntscr.com/mo505t
45 H A D G E H O G s
 
21.02.19
15:30
(41) Может база маленькая.

У меня
1 126 763 строк товаров
и
103 109 документов
46 IVT_2009
 
21.02.19
16:51
(45) документов 30 000, товаров 3000 примерно. Удивлен , что раньше не столкнулся с этим. Были подозрения на 1с
47 unregistered
 
21.02.19
16:59
(46) Не бог весть какой большой объём у (45).

А что с вопросом из (13)?
48 IVT_2009
 
21.02.19
17:01
(47) Просто ссылка на справочник Номенклатура
49 Вафель
 
21.02.19
17:07
а левое соединение нормально в итоговом запросеп формируется?.
Может на врутреннее переделать?
50 DrWatson
 
21.02.19
17:11
(46) Ну как все предложенные варианты попробовал?
Какая статистика, какой вариант сколько работает?
51 singlych
 
21.02.19
17:12
Короче, отбор до соединения оно явно не делает, хотя (22) с внутренним чуток быстрее, причем пофиг, отбор в ГДЕ или в ПО.
А вот ВТ с отобранными ссылками на доки решает. Ну или там вложенный.
52 IVT_2009
 
21.02.19
17:21
ВЫБРАТЬ
    расходнаяНакладнаятовары.Ссылка КАК Ссылка,
    расходнаяНакладнаятовары.НомерСтроки КАК НомерСтроки,
    расходнаяНакладнаятовары.нппПоТТН КАК нппПоТТН,
    расходнаяНакладнаятовары.товар КАК товар,
    расходнаяНакладнаятовары.количество КАК количество,
    расходнаяНакладнаятовары.цена КАК цена,
    расходнаяНакладнаятовары.сумма КАК сумма,
    расходнаяНакладнаятовары.идСправкаА КАК идСправкаА,
    расходнаяНакладнаятовары.идСправкаБ КАК идСправкаБ,
    расходнаяНакладнаятовары.Ссылка.WBRegId КАК WBRegId
ПОМЕСТИТЬ тбл_рез
ИЗ
    Документ.расходнаяНакладная.товары КАК расходнаяНакладнаятовары
ГДЕ
    расходнаяНакладнаятовары.Ссылка.WBRegId = &WBRegId
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    тбл_рез.Ссылка КАК Ссылка,
    тбл_рез.НомерСтроки КАК НомерСтроки,
    тбл_рез.нппПоТТН КАК нппПоТТН,
    тбл_рез.товар КАК товар,
    тбл_рез.количество КАК количество,
    тбл_рез.цена КАК цена,
    тбл_рез.сумма КАК сумма,
    тбл_рез.идСправкаА КАК идСправкаА,
    тбл_рез.идСправкаБ КАК идСправкаБ,
    тбл_рез.WBRegId КАК WBRegId
ИЗ
    тбл_рез КАК тбл_рез
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.номенклатура КАК номенклатура
        ПО (тбл_рез.товар = номенклатура.Ссылка)


Вот так то же очень быстро.
Выбрал содержимое ттн в таблицу и таблицу соединил со справочником. Блин , извращение однако
53 IVT_2009
 
21.02.19
17:23
поле забыл со кодом товара, сейчас переделал - то же очень быстро.
В оригинале запрос отрабатывал за 7 сек , сейчас доли секунды.
54 Вафель
 
21.02.19
17:24
А где параметры номенклатуры выбираются?
55 IVT_2009
 
21.02.19
17:24
(54) ВЫБРАТЬ
    расходнаяНакладнаятовары.Ссылка КАК Ссылка,
    расходнаяНакладнаятовары.НомерСтроки КАК НомерСтроки,
    расходнаяНакладнаятовары.нппПоТТН КАК нппПоТТН,
    расходнаяНакладнаятовары.товар КАК товар,
    расходнаяНакладнаятовары.количество КАК количество,
    расходнаяНакладнаятовары.цена КАК цена,
    расходнаяНакладнаятовары.сумма КАК сумма,
    расходнаяНакладнаятовары.идСправкаА КАК идСправкаА,
    расходнаяНакладнаятовары.идСправкаБ КАК идСправкаБ,
    расходнаяНакладнаятовары.Ссылка.WBRegId КАК WBRegId
ПОМЕСТИТЬ тбл_рез
ИЗ
    Документ.расходнаяНакладная.товары КАК расходнаяНакладнаятовары
ГДЕ
    расходнаяНакладнаятовары.Ссылка.WBRegId = &WBRegId
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    тбл_рез.Ссылка КАК Ссылка,
    тбл_рез.НомерСтроки КАК НомерСтроки,
    тбл_рез.нппПоТТН КАК нппПоТТН,
    тбл_рез.товар КАК товар,
    тбл_рез.количество КАК количество,
    тбл_рез.цена КАК цена,
    тбл_рез.сумма КАК сумма,
    тбл_рез.идСправкаА КАК идСправкаА,
    тбл_рез.идСправкаБ КАК идСправкаБ,
    тбл_рез.WBRegId КАК WBRegId,
    номенклатура.кодАпЕГАИС КАК кодАпЕГАИС
ИЗ
    тбл_рез КАК тбл_рез
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.номенклатура КАК номенклатура
        ПО (тбл_рез.товар = номенклатура.Ссылка)

в прошлом примере поле забыл. Результат тот же - быстро
56 H A D G E H O G s
 
21.02.19
17:31
Я бы тоже был бы быстр, если бы меня закешировали.
57 Hmster
 
21.02.19
17:40
А куда делось товарполнНаименование ?
58 IVT_2009
 
21.02.19
17:43
(57) проверил , тот же результат (быстро). Дело было все же в полях справочника. Тормозило в оригинале  при выборе любого поля справочника.
59 DrWatson
 
21.02.19
17:49
(56) В файловой есть кэш?
60 Cyberhawk
 
21.02.19
17:50
(58) А теперь перезагрузи хосты сервера 1С и сервера СУБД и замерь снова
61 Конструктор1С
 
21.02.19
17:56
(0) 5 секунд это разве критично?
62 timurhv
 
21.02.19
18:09
(61) увеличить количество документов в 2 раза, будет 10 секунд (условно) :)
63 palsergeich
 
21.02.19
18:20
(61) смотря где
64 singlych
 
21.02.19
18:36
У меня так получилось.
10000 спр, 10000 доков по 20 строк.
В отбор попадает 1 документ.
Индексы и разыменование по справочнику не повлияли.

// 0: ~4.45 с
ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка,
    ТЧ.ТестСпр КАК ТестСпр,
    ТЧ.ТестСпр.ТестРек КАК ТестСпрТестРек
ИЗ
    Документ.ТестДок.ТестТЧ КАК ТЧ
ГДЕ
    ТЧ.Ссылка.ТестРек = &ТестРек

// 1: ~3.11 с
ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка,
    ТЧ.ТестСпр КАК ТестСпр,
    ТЧ.ТестСпр.ТестРек КАК ТестСпрТестРек
ПОМЕСТИТЬ Рез
ИЗ
    Документ.ТестДок КАК Док
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ТестДок.ТестТЧ КАК ТЧ
        ПО Док.Ссылка = ТЧ.Ссылка
ГДЕ
    Док.ТестРек = &ТестРек    

// 2: ~3.11 с
ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка,
    ТЧ.ТестСпр КАК ТестСпр,
    ТЧ.ТестСпр.ТестРек КАК ТестСпрТестРек
ИЗ
    Документ.ТестДок КАК Док
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ТестДок.ТестТЧ КАК ТЧ
        ПО Док.Ссылка = ТЧ.Ссылка
        И Док.ТестРек = &ТестРек    

// 3: ~3.07 c
ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка,
    ТЧ.ТестСпр КАК ТестСпр
ПОМЕСТИТЬ ВТ
ИЗ
    Документ.ТестДок.ТестТЧ КАК ТЧ
ГДЕ
    ТЧ.Ссылка.ТестРек = &ТестРек
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ.Ссылка КАК Ссылка,
    ВТ.ТестСпр КАК ТестСпр,
    ВТ.ТестСпр.ТестРек КАК ТестСпрТестРек
ИЗ
    ВТ КАК ВТ

// 4: ~0.01 c
ВЫБРАТЬ
    Док.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ
ИЗ
    Документ.ТестДок КАК Док
ГДЕ
    Док.ТестРек = &ТестРек
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка,
    ТЧ.ТестСпр КАК ТестСпр,
    ТЧ.ТестСпр.ТестРек КАК ТестСпрТестРек
ИЗ
    Документ.ТестДок.ТестТЧ КАК ТЧ
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК ВТ
        ПО ТЧ.Ссылка = ВТ.Ссылка
65 Йохохо
 
21.02.19
18:45
(64) вариант 3 прямо находка для варианта 0
66 singlych
 
21.02.19
18:54
(65) Вариант 3 это то что в (55), только там <1 сек против 7ми, а у меня 3 сек против 4х.
67 singlych
 
21.02.19
19:07
А вот так, он по-ходу все-таки понимает, что отбор надо сделать раньше. Работает за 0.01, как с ВТ.

ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка,
    ТЧ.ТестСпр КАК ТестСпр,
    ТЧ.ТестСпр.ТестРек КАК ТестСпрТестРек
ПОМЕСТИТЬ Рез
ИЗ
    Документ.ТестДок КАК Док
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.ТестДок.ТестТЧ КАК ТЧ
        ПО Док.Ссылка = ТЧ.Ссылка
ГДЕ
    Док.ТестРек = &ТестРек
68 singlych
 
21.02.19
19:10
(55) Попробуй сделай у себя, как в (22)