|
v7: Внутренности черного запроса 7.7 - как правильнее писать? | ☑ | ||
---|---|---|---|---|
0
Злопчинский
29.05.18
✎
03:12
|
Допустим есть чорный запрос
//--------------------------------------------------------- Вариант-1 . |Груз = Регистр.Остатки.Груз; |НомерМеста = Регистр.Остатки.Груз.НомерМеста; ... |Условие(НомерМеста=0); //--------------------------------------------------------- Вариант-2 . |Груз = Регистр.Остатки.Груз; ... |Условие(глЗапрос.Груз.НомерМеста=0); Примечание: условие находится среди других условий в запросе Вопрос: как правильнее писать с точки зрения производительности запроса? оттранслированные во внутреннее представление варианты написания запросов эквивалентны или будут разные..? интересует для DBF базы, ну и для скульной не помешает ??? |
|||
1
Boleev
29.05.18
✎
03:27
|
Я за первый вариант, но что-то мне подсказывает, что клюшкам по-барабану если не используется 1с++.
|
|||
2
Зуекщмшср
29.05.18
✎
04:46
|
Насколько помню из своей бурной молодости, каждая лишняя точка в запросе увеличивает батхед головного мозга 1С 7.7. Я за второй вариант.
|
|||
3
DrZombi
гуру
29.05.18
✎
06:19
|
(0) Если нужна скорость, то пиши через прямые запросы.
Если побоку на производительность, то пиши как сумеешь, много не потеряешь, любой из двух вариантов отработает с равной скоростью :) |
|||
4
DrZombi
гуру
29.05.18
✎
06:21
|
+(0) И помни, если у вас SQL БД, то 1С 7.7 побоку на этот факт, она все ровно все потащит в папочку темп и будет все лепить через DBF прокладку :)
|
|||
5
dmitryds
29.05.18
✎
06:49
|
(2) это при последующей обработке в цикле
(в запросе надо получить все поля, которые будут использоваться при обработке встроенным языком, на первый уровень), а в самом запросе - фиг знает) |
|||
6
Владимир1С
29.05.18
✎
06:59
|
(4) Если тащить ссылки, то да, а если в прямых запросах ссылки не выводить, будет быстрее раза в 4 - 3 .
|
|||
7
RKx
29.05.18
✎
07:34
|
(0) Правильнее будет отобрать грузы по условию НомерМеста=0, а затем передать результат в отбор регистра.
|
|||
8
Shandor777
29.05.18
✎
08:25
|
(0) /Внутренности чорного запроса 7.7 - как правильнее писать/
Правильнее писать "чёрного" :) |
|||
9
cincout
29.05.18
✎
08:27
|
Правильнее так: Внутренности черного запроса 7.7
|
|||
10
oslokot
29.05.18
✎
08:36
|
(8) (9) Это олдскульная транскрипция. И у клюшек это именно чорный запрос, да.
|
|||
11
Провинциальный 1сник
29.05.18
✎
08:42
|
(10) В старых книгах, до 50-х годов, писали "чорт". На фоне в общем привычной прочей лексики это слегка шокирует.
|
|||
12
Зуекщмшср
29.05.18
✎
09:15
|
(11) Тогда бы Боярский в фильме кричал "Тысяча чОртей"!
|
|||
13
vcv
29.05.18
✎
09:38
|
Если SQL, то первый вариант. Его 7.7 разворачивает в нормальные join.
|
|||
14
Злопчинский
29.05.18
✎
12:06
|
(13) допустим.
а на DBF эти запросы во что транслируются? |
|||
15
Злопчинский
30.05.18
✎
18:37
|
(7) Это когда припрет если оптимизировать по скорости надо будет. Но так как в частности применения набор грузов небольшой и ограничен сверху отбором по заказу - то пока улучшать смысла нет.
|
|||
16
Злопчинский
30.05.18
✎
18:38
|
Так-с, специалист провел трассировку на DBF версии.
. Тестировались следующие варианты . //******************************************* Процедура кнВариант1() глЗапрос = СоздатьОбъект("Запрос"); ТекстЗапроса = " |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент; |Продажа = Справочник.Номенклатура.Сумма; |Коэффициент = Справочник.Номенклатура.БазоваяЕдиница.Коэффициент; |Условие(Коэффициент<>1); |Функция СуммаПродажа = Сумма(Продажа); |Группировка Номенклатура Упорядочить По Номенклатура.Код Без Групп; |"; Если глЗапрос.Выполнить(ТекстЗапроса)<>1 Тогда Возврат; КонецЕсли; ТЗ = ""; глЗапрос.Выгрузить(ТЗ,1,0); ТЗ.ВыбратьСтроку(,"Вариант1"); КонецПроцедуры //кнВариант1() //******************************************* Процедура кнВариант2() глЗапрос = СоздатьОбъект("Запрос"); ТекстЗапроса = " |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент; |Продажа = Справочник.Номенклатура.Сумма; |Единица = Справочник.Номенклатура.БазоваяЕдиница; |Условие(глЗапрос.Единица.Коэффициент<>1); |Функция СуммаПродажа = Сумма(Продажа); |Группировка Номенклатура Упорядочить По Номенклатура.Код Без Групп; |"; Если глЗапрос.Выполнить(ТекстЗапроса)<>1 Тогда Возврат; КонецЕсли; ТЗ = ""; глЗапрос.Выгрузить(ТЗ,1,0); ТЗ.ВыбратьСтроку(,"Вариант2"); КонецПроцедуры //кнВариант2() //******************************************* Процедура кнВариант3() глЗапрос = СоздатьОбъект("Запрос"); ТекстЗапроса = " |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент; |Продажа = Справочник.Номенклатура.Сумма; |Условие(глЗапрос.Номенклатура.БазоваяЕдиница.Коэффициент<>1); |Функция СуммаПродажа = Сумма(Продажа); |Группировка Номенклатура Упорядочить По Номенклатура.Код Без Групп; |"; Если глЗапрос.Выполнить(ТекстЗапроса)<>1 Тогда Возврат; КонецЕсли; ТЗ = ""; глЗапрос.Выгрузить(ТЗ,1,0); ТЗ.ВыбратьСтроку(,"Вариант3"); КонецПроцедуры //кнВариант3() |
|||
17
Злопчинский
30.05.18
✎
18:40
|
Далее номер пункта - это номер варианта. Нулевой пункт - общее для всех вариантов.
0) Все варианты пишут в одинаковую рабочую таблицу, одинаковое количество записей. Условия проверяется до записи в рабочую таблицу. Обрабатывается в ПостЗапросе рабочая таблица одинаково. 1) Просматривается последовательно таблица Номенклатура. Для каждой её записи производится поиск по ключу в таблице Единицы. Проверяется условие в оперативной памяти. Производится запись в рабочую таблицу, если условие - истина. Для движения по таблицам используется один и тот же объект "манипуляции" записями таблиц. Для каждой таблицы, естественно - свой. Создаются они в начале цикла. Освобождаются они в конце цикла. 2) Тоже, что и в (1). Но, на каждый поиск по ключу создаётся/освобождается объект "манипуляции" для таблицы Единицы. Процесс не очень быстрый. Т.к. выполняется просмотр (тупым перебором) в оперативной памяти схемы базы данных, созданной из файла 1Cv7.DD. Да и само создание объекта не мгновенное дело. 3) Тоже, что и в (2). Но, записи таблицы Номенклатура читаются по ДВА раза. С созданием объекта "манипуляции". С точке зрения ввода/вывода в терминальном режиме - это мелочи. Но, всё ж... :-) |
|||
18
Злопчинский
30.05.18
✎
18:49
|
Итого: самый быстрый вариант = Вариант1.
. Но! Вариант2 имеет при использовании чорных запросов вполне конкретное применение. Например, когда (почему - не обсуждаем) реквизит БазоваяЕдиница не типизирован жестко (Справочник неопределенного вида, наприме,р в БазовойЕдинице может быть Спр.Единицы и Спр.ДопЕдиницы) - то адресоваться напрямую в переменную запроса к реквизиту |Коэффициент = Справочник.Номенклатура.БазоваяЕдиница.Коэффициент; - не получится, при исполнении запроса выругается на неправильный путь к "Коэффициент" - тогда применение Варианта2 вполне прокатит. как-то вот так. |
|||
19
Djelf
30.05.18
✎
19:05
|
(16) Не помню чтобы кто-то такое мерял!
В закладки! На всякий случай... P.S. Что только люди не делают, чтобы избежать использования 1С++, фокса или 1sqlite :) Хотя, заказчики бывают упертые и знание штатных средств оптимизации необходимо. |
|||
20
Злопчинский
30.05.18
✎
19:31
|
(19) тут не вопрос в том, чтобы не использовать 1С++, фокс или скулайт - вопрос втом, что если необходимости в допсредствах нет - то не используем.
|
|||
21
Злопчинский
30.05.18
✎
19:32
|
тот же фокс - монопольно не пашет, если только не патчить.
а по скулайту у меня есть концептуальное недопонимание начальное... |
|||
22
Злопчинский
30.05.18
✎
19:35
|
и еще попутно (ранее озвучивалось).
дополнительные услвоия фильтрации на вычисление функций (КОГДА) отрабатывают уже на рабочей таблице, получившейся выборки. Поэтому если в запросе нет функции (без использования КОГДА) которая возвращает ненулевое значение "на сервере" - то запрос может получиться пустой... то бишь при использовании КОГДА в опредеделенных случаях надо юзать чтото типа |Функция Дамми = Сумма(1); //чтобы "на сервере" сформировалась выборка |
|||
23
Злопчинский
31.05.18
✎
16:58
|
(17) по пп 2) и 3) вместо "Тоже, что и в .." следует читать "То же, что и в..."
|
|||
24
Ёпрст
31.05.18
✎
17:12
|
(0)
только вар 1. Если вар 2 запустить в sql, можно и не дождаться выполнения запроса |
|||
25
Ёпрст
31.05.18
✎
17:13
|
а так, нужно лепить прямой запрос и забыть про чорные, навсегда.
|
|||
26
Ёпрст
31.05.18
✎
17:19
|
Ну и это, Чебур, ты для чорных запросов, хоть делаешь
глПередВыполнениемЗапроса ? |
|||
27
Ёпрст
31.05.18
✎
17:19
|
который выкидывает лишние переменные с текста запроса ?
Особенно актуально в типовых отчетах. |
|||
28
Злопчинский
31.05.18
✎
17:40
|
(26) Не не делаю, если есть - скинь сюда
Я сейчас кропаю очередную нетленку ;-) Запросы формирую динамически, минимум необходимого в текст запроса пихаю. |
|||
29
Злопчинский
31.05.18
✎
17:54
|
(27) у меня есть глобальная непонятка и я постоянно стремаюсь...
Когда есть переменные запроса, не участвующие в группировках, но нужные в результатах запроса 1. Какой в этом смысл, ведь на уровне группировки переменная запроса, не участвующая в группировке, не будет иметь смысла - так? 2. Переменные запроса имеют смысл только на том уровне группировки, которая соответствует "уровню" переменной? - так? то есть если мы обращаемся к переменной запроса типа Запрос.ЧтоТоИзРеквизитовШапкиДокумента - то это будет иметь смысл только если мы находимся на уровне группировки "Документ" - так? |
|||
30
vcv
31.05.18
✎
20:31
|
(28) Не моё ли поделие имеется в виду?
http://catalog.mista.ru/public/64620/ |
|||
31
vcv
31.05.18
✎
20:41
|
(29) >> Какой в этом смысл
Глобальный смысл сократить индексное выражение. По всем группировкам 1С делает один сборный индекс и он, к сожалению, ограничен по длине выражения. Большое количество группировок (штук десять и меньше, если есть строковые значения) приводит к ошибке "Длина индекса превышает максимальную длину и не может быть уменьшена". Ну и проще индекс - быстрее обработка запроса. >> Переменные запроса имеют смысл только на том уровне >> группировки, которая соответствует "уровню" переменной? Примерно так. Удобно, когда нужно, например, в отчёте с номенлатурой показать артикул, код, базовую единицу... Это всё можно получить запросом. Будет быстрее, чем в процессе вывода таблицы отчёта для каждой строки отчёта дёргать базу для получения реквизитов номенклатуры. |
|||
32
Djelf
31.05.18
✎
21:09
|
Могу быть не прав, но...
- смотрим на индекс в DD, - если мы в какой то индекс можем попасть, указываем условия в порядке индекса - если индекса нет, указываем условия по такому порядку чтобы выборка поменьше (какой индекс выбрать склад или номенклатура?. Это зависит от того сколько складов и сколько номенклатуры) А еще можно вырубить 1с во время запроса и посмотреть что там за данные и индексы оно сотворило... P.S. А sqlite это ты зря! (upsert уже почти есть, но это не так интересно для баз 7.7 /для внешних вкусно/). А скоро будет и с оконными функциями. Вкусно, вкусно... |
|||
33
Злопчинский
31.05.18
✎
21:27
|
(32) да я ж только за! скулайт. у мну непонимание начальное концептуальное есть - а где почитать с азов, так чтобы понимать какие операторы в самом начале примененяи скулайта писать (что там как определять таблицы в мемори и прочее - как-то не встречалось.
|
|||
34
Djelf
31.05.18
✎
21:40
|
(33) Вечная недоделка... Времени на нее не очень есть ;(
https://cloud.mail.ru/public/DsqW/V4c39Td9o |
|||
35
Злопчинский
31.05.18
✎
21:54
|
(34) ну значит надо бросать и переходить на снеговика, там, говорят, как в раю - всё уже есть и практически даром...
|
|||
36
Злопчинский
31.05.18
✎
23:19
|
(31) Как моэно сократить "индексное выражение" если речь идет о переменных, не входящих ни в группировки, ни в условия?
|
|||
37
Boleev
01.06.18
✎
02:17
|
Нетленка на 7.7? почему на на перфокартах?
|
|||
38
Злопчинский
01.06.18
✎
02:37
|
(37) При необходимости если упереться я могу для БЭСМ-6 на forex (вроде так назывался) налабать... или на ADABASe.. или на ассемблере для ЕСок, на перфокартах не смогу - бармалея в личном распоряжении нет...
|
|||
39
Злопчинский
01.06.18
✎
02:38
|
(37) .. и потому что - самая короткая дорога - та, которую знаешь.. ;-)
|
|||
40
Maniac
01.06.18
✎
02:40
|
самое быстрое если номер груза - основное к чему регулярно обращаются - сделать его измерением.
Вижу что итак регистр остатков в котором есть груз - какая то офигенная нетленка |
|||
41
Maniac
01.06.18
✎
02:41
|
а так в челом если Номер места тип число. то вообще поуху.
Этот тип не ресурсоемкий. Через много точек - скорость зависит от того на каком месте это измерение Груз в регистре. Включена ли галка на нем |
|||
42
Maniac
01.06.18
✎
02:43
|
Если оно там 5-6-7 по счету, есть смысл задуматься о том чтобы сделать новый регистр.
Семерка и куча измерений - начинает вешаться и на запись и на чтение. Идеально для 77 это 5 измерений, не больше. А лучше 4 |
|||
43
Maniac
01.06.18
✎
02:45
|
вообще 77 удивительная платформа, в которое от положения регистре может вершится судьба
|
|||
44
Maniac
01.06.18
✎
02:52
|
Если память не отшибло в типовой ТИС измерения склад и номенклатура располодены так что если сдвинуть номенклатуру на первое место и переписать методы Остатки и СводныОстаток то скорость просто без использования даже 1С++ может в тысячу раз увеличится и размер дбф и индекса уменьшиться
|
|||
45
Maniac
01.06.18
✎
02:55
|
Братан если ты не в курсе того что я написал. То ты полжизни работы на 77 даже потратил зря.Сдвигать измерения в 1С без потери данных, и всего навсего 2 метода в 77 где надо местами переменные поменять, и то их там будет с десяток.
Переидексация базы автоматическая, и жизнь играет в новых красках. |
|||
46
vcv
01.06.18
✎
05:41
|
(44) Легенды нашего городка?
С быстродействием еще ладно. Изменяется по факту. В зависимости от обращений к регистру. При проведении документа фирма, склад и номенклатура известны, значит все компоненты сборного индекса есть. От перестановки мест в индексе вряд ли что-то сильно поменяется. Всё остальное в зависимости от данных и алгоритмов. Если переместить номенклатуру на первое место, получение отчёта по складским остаткам должно замедлиться. Пропорционально количеству фирм и складов. Но, конечно, перестановка измерений меняет индекс. Последствия могут быть серьёзные в обе стороны. Когда на SQL начинаешь пользоваться прямыми запросами, в полной мере осознаёшь разницу между index seek, index scan, table scan. А размер файлов-то почему изменится? Не вижу к этому вообще никаких предпосылок. |
|||
47
МихаилМ
01.06.18
✎
06:03
|
эта тема обсуждалась на этом форуме лет 10 назад.
и приводились примеры, что конструкцией условие (запрос.) лучше не пользоваться , тк иногда выдаётся неверный результат. |
|||
48
Злопчинский
01.06.18
✎
11:30
|
(40) Маня, ты не поверишьЮ но в складской логистике - это сплошь и рядом. и я бы даже сказал - норма. Мир ведь не замкнулся на твоих лавочниках с автозапчастями.
|
|||
49
Злопчинский
01.06.18
✎
11:31
|
(47) "условие (запрос.) лучше не пользоваться , тк иногда выдаётся неверный результат."
- а не помнишь в чем там было дело? |
|||
50
Эльниньо
01.06.18
✎
11:52
|
(37) Перфокарта - вчерашний день. Перфолента и только перфолента.
|
|||
51
Salimbek
01.06.18
✎
12:20
|
(33) Как-то так:
и обработка 1sqlite.ert для отладки и оптимизации запросов |
|||
52
Злопчинский
01.06.18
✎
12:34
|
(51) база.Открыть(":memory:");
- это перед каждым запросом надо делать? надо после запроса как-то "закрывать"..? или достаточно сделать база.Открыть(":memory:"); - один раз на весь сеанс и шпарить любые запросы? |
|||
53
Salimbek
01.06.18
✎
13:01
|
(52) Код из внешней обработки для стандартной ТиС, поэтому открывается один раз в ПриОткрытии, база - переменная модуля формы.
Вообще, как мы помним, 1С-ка не мультизадачная, поэтому даже рс = база.НовыйЗапрос(); можно вынести в ПриОткрытии и дальше все запросы делать с использованием этого одного РекордСета. Был правда случай из практики - когда пришлось одновременно два запроса в цикл дергать, там было проще сделать два РС-а с разными подготовленными запросами. ... Подготовленные запросы это так (Добавляем в документ товары из файла, по полученному ШтрихКоду): ТекстЗапроса="select parentext [Товар :Справочник.Номенклатура] from Справочник_Единицы where Штрихкод=@ШК"; рс.Подготовить(ТекстЗапроса); Табличка=стДок.Document_Table; тзДок = СоздатьОбъект("ТаблицаЗначений"); Док.ВыгрузитьТабличнуюЧасть(тзДок); Для Сч=1 По Табличка.Количество() Цикл тзДок.НоваяСтрока(); лкСтрока=Табличка.Получить(Сч); рс.УстановитьПараметр("@ШК", лкСтрока.Barcode); тз=рс.Выполнить(); тзДок.ВидТМЦ = Перечисление.ВидыТМЦ.Товар; тзДок.Номенклатура = тз.ПолучитьЗначение(1,1).ТекущийЭлемент(); |
|||
54
Salimbek
01.06.18
✎
13:07
|
Еще пример запроса из той же обработки, демонстрирует использование доп_полей (1SQLite дает возможность запроса к индексированному выражению, как к отдельному полю, для гарантированного попадания)
Выбираем все документы за Период из Журнала складских документов с отбором по указанному Складу ТекстЗапроса=" |select G.iddocdef iddocdef, G.iddoc iddoc, CHILDDATE, str2id(CHILDTIME)/10000 chTime, G.iddocdef || G.iddoc [d :Документ], | shk | ,R.Количество * (1-2*R.DEBKRED) Kol |from (select * from Журнал where DATE between :НачДата and :КонДата) G | inner join __1S_crdoc O | on o.idx_MDID_PARENTVAL_CHILDDATE_CHILDTIME_CHILDID= | :ГрафаОтбора.Склад || 'B1 1J' || :Склад || ' '||g.DATE||g.TIME||g.iddoc | inner join Регистр_ОстаткиТМЦ R on g.iddoc=R.iddoc | left join tSh S | ON R.Номенклатура=S.pid |Where R.Склад=:Склад |order by CHILDDATE, CHTIME, IDDOC |"; |
|||
55
Djelf
01.06.18
✎
13:08
|
(52) Если у тебя глБаза то только один раз.
Если лБаза в обработке то надо инициализировать. Закрывать не обязательно - сама закроется при уничтожении объекта. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |