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