|   |   | 
| 
 | 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) Если у тебя глБаза то только один раз.
 Если лБаза в обработке то надо инициализировать. Закрывать не обязательно - сама закроется при уничтожении объекта. | 
 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |