Имя: Пароль:
1C
1С v8
Можно ли оптимизировать такой запрос
,
0 MrZLO
 
18.09.15
08:51
Узнать количество реализованных товаров из заказа покупателя... 14 секунд время выполнения... :(((


ВЫБРАТЬ
                       СУММА(ЕСТЬNULL(РеализацияТоваровУслугТовары.Количество, 0)) КАК КоличествоРеализации,
                       РеализацияТоваровУслугТовары.Номенклатура
                   ИЗ
                       Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
                   ГДЕ
                       РеализацияТоваровУслугТовары.Ссылка.ДокументОснование = &Ссылка
                       И РеализацияТоваровУслугТовары.Ссылка.Проведен = ИСТИНА
                       И РеализацияТоваровУслугТовары.Ссылка.ДокументОснование <> &ПустаяСсылка
                  
                   СГРУППИРОВАТЬ ПО
                       РеализацияТоваровУслугТовары.Номенклатура
1 butterbean
 
18.09.15
08:52
в регистре Продажи отбор по измерению Сделка
2 Jonny_Khomich
 
18.09.15
08:52
делай запрос к регистрам
3 vogenut
 
18.09.15
08:54
(0)
РеализацияТоваровУслугТовары.ДокументОснование = &Ссылка
                       И РеализацияТоваровУслугТовары.Проведен = ИСТИНА
                       И РеализацияТоваровУслугТовары.ДокументОснование <> &ПустаяСсылка
4 Jonny_Khomich
 
18.09.15
08:55
(3) в ТЧ такого реквизита нет!
5 MrZLO
 
18.09.15
08:56
(4) его сами добавляли в свое время
6 Dmitriy_76
 
18.09.15
08:57
тут похоже дело не в запросе..а в железе...
не может выбор тч из конкретного документа так долго выполнятся..
7 Jonny_Khomich
 
18.09.15
08:58
РеализацияТоваровУслугТовары.Ссылка.ДокументОснование <> &ПустаяСсылка - это условие тормозит
8 Маратыч
 
18.09.15
08:59
Уу... а регистры куда дели?
9 vogenut
 
18.09.15
08:59
(4) Сорри, не увидел табличную часть
(7) Да, из-за этого скан будет таблицы РеализацияТоваровУслуг
10 Cyberhawk
 
18.09.15
08:59
(6) "не может выбор тч из конкретного документа" // у него в запросе нет условия на конкретный документ...
11 adron
 
18.09.15
09:00
Попробуй сначала выбрать просто расходки, по условию документ основание, без табличных частей - получишь несколько ссылок. Затем запрос к табличным частям, и суммирование количества...
12 User_Agronom
 
18.09.15
09:03
РеализацияТоваровУслугТовары.Ссылка.ДокументОснование = &Ссылка
...
И РеализацияТоваровУслугТовары.Ссылка.ДокументОснование <> &ПустаяСсылка

Если первое условие истина, второе истина однозначно.
Грохай.

РеализацияТоваровУслугТовары.Ссылка.Проведен = ИСТИНА

заменить на  РеализацияТоваровУслугТовары.Ссылка.Проведен
13 Jonny_Khomich
 
18.09.15
09:03
(8) сегодня питница, можно и без них
14 Cyberhawk
 
18.09.15
09:05
(12) РеализацияТоваровУслугТовары.Ссылка.Проведен = ИСТИНА

заменить на  РеализацияТоваровУслугТовары.Ссылка.Проведен // это где-то описан такой способ оптимизации?
15 User_Agronom
 
18.09.15
09:06
&ПустаяСсылка писать так плохо. Нужно:  ЗНАЧЕНИЕ(Документ.ЗаказПокупателя.ПустаяССылка) (тип документа нужный укажи)
16 Jonny_Khomich
 
18.09.15
09:06
Запрос делал к документу (млн. записей в день), если делать условие на проведение документа и на период, то выполнение запроса затягивалось на 5 минут, без условия на проведение пару секунд.
17 User_Agronom
 
18.09.15
09:08
(14) Хз. Помнится во времена моей юности ОЗУ было ограничено, и мы, сдавая студенческие работы, экономили каждую операцию. Так вот: операция "=" занимает место и время. Я не уверен про SQL, но для любого языка программирования это так.
18 Jonny_Khomich
 
18.09.15
09:11
(17) а ты знаешь, что 1с строит план запроса?
Это как на курсах по оптимизации вопросов преподаватель советовал расставлять условия запроса в определенном порядке, хотя на деле никакого прироста к производительности не было
19 Jonny_Khomich
 
18.09.15
09:11
(18) *оптимизация запросов
20 Jonny_Khomich
 
18.09.15
09:12
(17) в каком году это было? Я в 2003 уже думал о таком и преподаватели не говорили об этом.
21 НЕА123
 
18.09.15
09:13
(0)
может во временную таблицу сначала список нужных доков?
потом отбор только по ним.
ЗЫ
две точки - не кошерно.
22 hhhh
 
18.09.15
09:19
И РеализацияТоваровУслугТовары.Ссылка.ДокументОснование <> &ПустаяСсылка
                  
выкинуть

ДокументОснование   проиндексировать

или период задать. Например месяц.
23 User_Agronom
 
18.09.15
09:20
(18) ...а ты знаешь, что 1с строит план запроса...
Знаю. Поэтому не готов поручится про SQL.

...расставлять условия запроса в определенном порядке...

Ну давай ещё что-нибудь приведи извращенное.

Я могу сказать, что код
Если а>=б тогда
   Значение = Истина
Иначе
  Значение = ложь;
КонецЕсли

Имеет один оператор ветвления, одно сравнение и два оператора присваивания.

А код с таким же результатом:

Значение = а>=б;

имеет один оператор сравнения и один присваивания.

Этот код однозначно будет занимать меньше памяти (для Trubo Pascakal 3.0 оператор присваивания 2 байта, полный оператор ветвления уже не помню - то ли 10, то ли 12) + текст программы тоже содержался в ОЗУ (байт на символ, включая конец строки и возврат каретки).
24 asady
 
18.09.15
09:20
ВЫБРАТЬ
                       СУММА(ЕСТЬNULL(РеализацияТоваровУслугТовары.Количество, 0)) КАК КоличествоРеализации,
                       РеализацияТоваровУслугТовары.Номенклатура
                   ИЗ
                       Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Док ПО РеализацияТоваровУслугТовары.Ссылка=Док.Ссылка
                   ГДЕ
                       Док.ДокументОснование = &Ссылка
                       И Док.Проведен
                  
                   СГРУППИРОВАТЬ ПО
                       РеализацияТоваровУслугТовары.Номенклатура
25 НЕА123
 
18.09.15
09:23
(23)
+
"ГДЕ" заменить на "И".
26 НЕА123
 
18.09.15
09:24
*
(25)->(24)
27 Матиус
 
18.09.15
09:33
(16) Условие
.Дата МЕЖДУ &ДатаНач И &ДатаКон
работает однозначно быстрее чем
.Дата >= &ДатаНач И .Дата <= &ДатаКон
28 Матиус
 
18.09.15
09:34
(27) а, у тебя проведение. забудь
29 User_Agronom
 
18.09.15
09:35
(20) В начале 199х.
30 Матиус
 
18.09.15
09:40
(23) Операторы, байты, милисекунды... Что ты мучаешься, пиши как проще, не в каменном веке живем. Сейчас компы шустрые, все вытянут.
31 zak555
 
18.09.15
09:42
Автор, документ делает движения по регистрам
Данные надо оттуда брать
32 1Сергей
 
18.09.15
09:45
и естьнулл тут не нужен
33 User_Agronom
 
18.09.15
09:48
(30) Я с этого начинал. Тебе просто этого не понять.
Я сейчас часто замечаю, что код, написанный мной, гораздо короче кода, написанного другими программистами - при условии одинакового результата. А чем меньше кода, тем меньше там ошибок ;)
34 Bober
 
18.09.15
09:49
(0)
1. выполнить рекомендации (12) (32), посмотреть есть ли индекс у поля ДокументОснование.
2. Как часто выполняются регламентные задания по обслуживанию индексов.
35 MrZLO
 
18.09.15
10:01
(34) там вообще индекса не было, поставил, попробую переиндексировать базу - напишу результат
36 Гёдза
 
18.09.15
10:07
каков план запроса?
37 Гёдза
 
18.09.15
10:09
(27) МЕЖДУ в SQL разворачивается как больше и меньше
38 senior
 
18.09.15
10:17
(0) про индексацию поля ДокументОснование уже говорили?
39 Ненавижу 1С
 
гуру
18.09.15
10:26
(0) сделай лучше по оборотам регистра Продажи
40 senior
 
18.09.15
10:28
(0) ну и что запрос по документам это моветон, само собой разумеется
41 GANR
 
18.09.15
10:30
(0) .Ссылка. - это убрать
42 GANR
 
18.09.15
10:31
+создать регистр накопления (читай денормализовать данные)
43 GANR
 
18.09.15
10:32
+(42) если нету
44 MrZLO
 
21.09.15
08:02
всем спасибо!!! реквизит РеализацияТоваровУслугТовары.ДокументОснование сделал индексируемым, переиндексировал базу и чудо свершилось, стало работать очень быстро все :)
45 Матиус
 
21.09.15
23:51
(33) Ну да, куда уж нам сирым и убогим понять тебя, о Гений 1С II с агрономическим складом ума.
46 Матиус
 
21.09.15
23:54
(33) Продолжай в том же духе, со временем научишься оптимизировать не только количество строчек с неизменным результатом, но и скорость со стабильностью.
47 ViSo76
 
22.09.15
00:40
Автору и всем кто чего то пытался придумать кроме 1 поста оценка кол. Тут и без индекса будет работать быстро нужно только переделать запрос. Топикастр берет большую таблицу соединяет левым соединением с главной и потом фильтрует. Это как штаны одевать через голову... А другие еще дают советы как фильтр проаптимизировать... тоесть на один if сделать меньше.
48 Бертыш
 
22.09.15
04:27
(33) Помню на ассемблере была короткая пара команд которая вешала комп намертво. Два байта всего
cli ;запретить внешние прерывания
hlt ;перевести цпу в режим ожидания внешних прерываний

потом ради конвеера и предвыборки пришлось к ним один jmp добавить
49 ЧеловекДуши
 
22.09.15
08:02
(0) ЕСТЬNULL(РеализацияТоваровУслугТовары.Количество

бессмысленный "ЕСТЬNULL", там никогда не будет нула  :)
50 ЧеловекДуши
 
22.09.15
08:05
(24) >>> ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Док ПО

Лишнее это, по ссылке все найдется :)
51 ЧеловекДуши
 
22.09.15
08:08
+(0) >>> РеализацияТоваровУслугТовары.Ссылка.ДокументОснование = &Ссылка

Используй в составе

РеализацияТоваровУслугТовары.Ссылка.ДокументОснование Ссылка Документ.ТвойДокумент

Ведь вид документа тебе известен, зачем все доументы просматривать?
На тот случай, если "ДокументОснование " составного типа :)
52 Широкий
 
22.09.15
09:13
"РеализацияТоваровУслугТовары.Ссылка.ДокументОснование = &Ссылка
И РеализацияТоваровУслугТовары.Ссылка.Проведен = ИСТИНА
И РеализацияТоваровУслугТовары.Ссылка.ДокументОснование <> &ПустаяСсылка"

Оставить только:
РеализацияТоваровУслугТовары.Ссылка.ДокументОснование = &Ссылка
И РеализацияТоваровУслугТовары.Ссылка.Проведен

И проверить есть ли индекс по реквизиту "ДокументОснование"
53 ViSo76
 
22.09.15
09:23
Вот текст запроса который не шибко будет проседать если индекса нет по документу основания.

ВЫБРАТЬ
   РеализацияТоваровУслугТовары.Номенклатура,
   СУММА( РеализацияТоваровУслугТовары.Количество ) КАК КоличествоРеализации
ИЗ
    Документ.РеализацияТоваровУслуг КАК докРеализация

    ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
        ПО докРеализация.Ссылка = РеализацияТоваровУслугТовары.Ссылка
ГДЕ
   докРеализация.Дата >= &ДатаДокументаОснования
   И докРеализация.ДокументОснование = &ДокументОснование
   И докРеализация.Проведен = ИСТИНА

СГРУППИРОВАТЬ ПО
   РеализацияТоваровУслугТовары.Номенклатура
54 Широкий
 
22.09.15
09:29
(53) Ты написал тоже самое.
"не шибко будет проседать" - за счет условия по дате
55 User_Agronom
 
22.09.15
09:38
(48) Ну это в каждом языке возможно. Если изучать его в юности. Например:

Program vse;
{$ уже не помню директиву процессору отключить прерывания типа CTRL+C и т.д.}
begin
while false do;
end.
56 Necessitudo
 
22.09.15
09:39
(18) 1C строит план запроса??
57 Зеленый пень
 
22.09.15
10:09
Странно, почему-то нет самого очевидного варианта:

ВЫБРАТЬ
    Ссылка
ПОМЕСТИТЬ ДокументыРеализации
ИЗ
    Документ.РеализацияТоваров КАК РеализацияТоваров
ГДЕ
    РеализацияТоваров.ДокументОснование = &Ссылка
    И РеализацияТоваровУслугТовары.Проведен
    И РеализацияТоваров.ДокументОснование <> &ПустаяСсылка
    
;

ВЫБРАТЬ
    СУММА(ЕСТЬNULL(РеализацияТоваровУслугТовары.Количество, 0)) КАК КоличествоРеализации,
    РеализацияТоваровУслугТовары.Номенклатура
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ГДЕ

    РеализацияТоваровУслугТовары.Ссылка В(ВЫБРАТЬ Ссылка ИЗ ДокументыРеализации)
                  
СГРУППИРОВАТЬ ПО
    РеализацияТоваровУслугТовары.Номенклатура
58 ViSo76
 
22.09.15
10:26
(54) Ты в этом уверен что 1С постоит для MS SQL такой же запрос как и у меня?
59 Гёдза
 
22.09.15
10:34
план запроса уже был?
60 ViSo76
 
22.09.15
10:43
(57) Месье знает толк в извращениях... мало что он временную базу использует tempdb что может сказаться на времени исполнении так и использование in для одного значения...

PS: От куда вы такие приходите в программирование поделитесь опытом?
61 trad
 
22.09.15
10:44
(60) почему in для одного?
62 Зеленый пень
 
22.09.15
10:46
(60) Для эстетов - можно выполнить первую часть запроса и использовать параметр для второго в условии "=". Но разницы в скорости не будет.
63 ViSo76
 
22.09.15
10:49
(61) Да обычно реализация в единственном экземпляре
(62) Нужно писать нормально как я написал в (53) а не хернёй страдать.
64 trad
 
22.09.15
10:51
(63) обычно != всегда
65 Зеленый пень
 
22.09.15
10:52
(63) Вариант (53) - очень спорный. Соединения больших таблиц лучше избегать.
66 ViSo76
 
22.09.15
11:07
(65) Где ты видишь соединение больших таблиц?
Условие будет наложено до соединения таблиц останется там пшик записей и потом соединение по первичному ключу
67 Зеленый пень
 
22.09.15
11:08
(66) Тогда в чем отличие от (0) ? "Через точку"  - точно такое же соединение.
68 НЕА123
 
22.09.15
11:12
(66)
>Условие будет наложено до соединения таблиц останется там пшик записей и потом соединение по первичному ключу
?

в данном запросе вытащится вся таблица
Документ.РеализацияТоваровУслуг.Товары

ГДЕ потом только отработает.

(57)+1
ну ЕстьNULL убрать можно и проверку на пустую ссылку.
69 ViSo76
 
22.09.15
11:18
(68) Ты так в этом уверен? Наверное смотрел план исполнения запроса?
(67) Покажи запрос который будет составлен для MS SQL
Вероятнее всего 1С построил запрос так:

select
...
from
  Документ.РеализацияТоваровУслуг.Товары as Tab_01

  left join Документ.РеализацияТоваровУслуг as Tab_02
    on ...

where
  Tab_02.ДокументОснование = &Ссылка

Тут будет как раз полное соединение а потом фильтрация о чём говорит 14 секунд.
70 Зеленый пень
 
22.09.15
11:40
В общем, все варианты одинаковы (прогнал на SQL), чего и следовало ожидать при правильной работе индекса по "ДокументОснование". Но я предпочитаю вариант написания, когда у SQL как можно меньше вариантов выбора.
Если поле "ДокументОснование" не индексировать, то единственный вариант ускорения - накладывать условие на период (например, дата реализации > даты заказа).
71 ViSo76
 
22.09.15
11:48
(70) В моём варианте у 1С сообще нет выбора как построить запрос для SQL он будет ровно таким как у меня без всяких неожиданностей в версиях платформы
72 ЧеловекДуши
 
22.09.15
11:53
(71) Бывает и сам SQL оптимизирует запрос :)
73 ViSo76
 
22.09.15
11:56
Да он и наложит перед соединением таблиц условия в where и выберет в моём случае индекс date если конечно индекса не будет по полю документ основание. Иначе он выберет индекс по полю документ основание.
74 ViSo76
 
22.09.15
12:04
(72) Да и к стати он это всегда делает в первый раз парсит и строит план исполнения к примеру если есть индекс по полю документ основание то MS SQL первым условием отбора будет использовать докРеализация.ДокументОснование = &ДокументОснование, а потом другие проверки. Так как в индекс Data смысла нет просматривать и это условие докРеализация.Дата >= &ДатаДокументаОснования будет проверенно уже на отобранных данных а не в индексе.
75 ЧеловекДуши
 
22.09.15
12:17
(74) Ага, и в итоге можно получить не совсем то, что ожидалось :)