Про оптимальность, производительность (реквизиты от ссылки через точку)
Известно, что при обращении к реквизиту (от ссылки) через точку, делается запрос к БД, при этом, получаются данные по всем реквизитам и табличным частям, а затем из этих данных выбирается значение, имя которого следует после точки.
Например:
Вероятно, аналогично будет с такой конструкцией:
Когда реквизитов, табличных частей в объекте не много, это не критично, но когда много, делать такие запросы - это не оптимально. Особенно, это будет заметно при обращении через точку в теле какого-то цикла.
Вопросы: зачем вообще в платформу добавлена такая не оптимальная возможность обращения к реквизитам, через точку, где её можно использовать? Есть ли какие-то простые и удобные способы получения значения одного реквизита, имея ссылку, кроме формирования текста запроса динамически?
Например:
Контр = Справочники.Контрагенты.НайтиПоНаименованию("Фирма 777", Истина);
ИНН = Контр.ИНН; // здесь будут получены все данные по ссылке и из полученного будет выбран ИНН
Сообщить("ИНН: " + ИНН);
Вероятно, аналогично будет с такой конструкцией:
ИНН = Контр["ИНН"];
Когда реквизитов, табличных частей в объекте не много, это не критично, но когда много, делать такие запросы - это не оптимально. Особенно, это будет заметно при обращении через точку в теле какого-то цикла.
Вопросы: зачем вообще в платформу добавлена такая не оптимальная возможность обращения к реквизитам, через точку, где её можно использовать? Есть ли какие-то простые и удобные способы получения значения одного реквизита, имея ссылку, кроме формирования текста запроса динамически?
По теме из базы знаний
- Концепция автоматизации многопрофильного Холдинга в системе АУБ на платформе 1С
- Повышение качества разработки. Статья 3. Ошибки программы
- Конфигурация Flowcon: Набор инструментов для управления задачами, проектами и бизнесом в 1С
- Таблицы серверов (как просто выбрать сервер)
- Распространенные ошибки разработчиков, приводящие к проблемам производительности
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(3)
Смиритесь.
Либо все писать оптимально самому, либо использовать библиотечное, может не очень оптимальное, зато уже существующее.
Причем если писать самому, совсем не факт, что у вас получится оптимальное решение. Косяки могут быть везде.
Если нужен один реквизит одного объекта, то данная функция общего модуля позволит его достаточно оптимально получить. Как минимум, оптимальнее, чем через точку от ссылки.
Тоже не очень оптимально.
Смиритесь.
Либо все писать оптимально самому, либо использовать библиотечное, может не очень оптимальное, зато уже существующее.
Причем если писать самому, совсем не факт, что у вас получится оптимальное решение. Косяки могут быть везде.
Если нужен один реквизит одного объекта, то данная функция общего модуля позволит его достаточно оптимально получить. Как минимум, оптимальнее, чем через точку от ссылки.
(2)
Только в "ОбщегоНазначения.ЗначениеРеквизитаОбъекта" и такая же "ЗначенияРеквизитовОбъекта" кода на 250 строк + вызовы функций/процедур из других модулей. И это только для того, чтобы получить реквизит у ссылки, который и так можно получить, просто обратившись по имени через точку или через [], если точно знаешь, что этот реквизит есть :-)
Возвращает функция "ЗначенияРеквизитовОбъекта" структуру. Структура это работа с динамической памятью. И далее обращение к элементам структуры - это тоже обращение либо через точку либо по имени поля.
ЗначениеРеквизита = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка,ИмяРеквизита);
Вызов функции/процедуры это дополнительное использование стека, исполнение кода - это работа интерпретатора + исполнения текста на языке 1С самой процедуры/функции с попытками исключения и обращения к метаданным, построение динамического текста запроса. Разбор строки с именами полей через разделитель.
Только в "ОбщегоНазначения.ЗначениеРеквизитаОбъекта" и такая же "ЗначенияРеквизитовОбъекта" кода на 250 строк + вызовы функций/процедур из других модулей. И это только для того, чтобы получить реквизит у ссылки, который и так можно получить, просто обратившись по имени через точку или через [], если точно знаешь, что этот реквизит есть :-)
Возвращает функция "ЗначенияРеквизитовОбъекта" структуру. Структура это работа с динамической памятью. И далее обращение к элементам структуры - это тоже обращение либо через точку либо по имени поля.
(18)
Для использования БСП в части работы с теми же адресами, необходимо в объекте предусмотреть табличную часть "КонтактнаяИнформация", вместо того, что бы хранить такую информацию в отдельной структуре.
А чтобы не тянуть адресную информацию каждый раз при обращении к объекту, из-за такой структуры данных (с табличной частью), необходимо использовать отдельную функцию.
И всё это что бы отделить БСП от прикладного решения. Ранее же контактная информация хранилась в отдельном регистре и у этого РС было измерение объект составного типа.
Т.е. каждый раз при решении проблемы создается очередная проблема, которая потом героически решается с созданием следующей. :-) Я ничего не упустил.
При обращении через точку по ссылке - тянуться и данные табличных частей.
Интересно получается.
Для использования БСП в части работы с теми же адресами, необходимо в объекте предусмотреть табличную часть "КонтактнаяИнформация", вместо того, что бы хранить такую информацию в отдельной структуре.
А чтобы не тянуть адресную информацию каждый раз при обращении к объекту, из-за такой структуры данных (с табличной частью), необходимо использовать отдельную функцию.
И всё это что бы отделить БСП от прикладного решения. Ранее же контактная информация хранилась в отдельном регистре и у этого РС было измерение объект составного типа.
Т.е. каждый раз при решении проблемы создается очередная проблема, которая потом героически решается с созданием следующей. :-) Я ничего не упустил.
(20) Контактная информация да, не критично.
Хуже, когда надо получить реквизит шапки какого-то документа, у которого 5 табличных частей, в которых больше 10 тыс. строк, и реквизитов табличных частей более 20.
Мне просто попалась конфа, разработанная подрядчиками (франчайзи), где в нескольких местах встречаются конструкции примерно такого вида:
У франча нет программистов не специалистов, т.е., без сертификатов.
Но это же капец, нет?
Суть в том, что по самописному обмену (через web-сервис) приходят данные разных видов документов, заносятся в структуру, структура дополняется ссылками на существующие в базе документы и перед записью документов таким образом проверяется, изменились данные или нет.
То же самое делается для табличных частей.
И еще, уже после записи сделанные изменения сохраняются в регистр, где снова отрабатывают примерно такие же циклы, чтобы определить, что именно записать в регистр.
🤦♂️
Хуже, когда надо получить реквизит шапки какого-то документа, у которого 5 табличных частей, в которых больше 10 тыс. строк, и реквизитов табличных частей более 20.
Мне просто попалась конфа, разработанная подрядчиками (франчайзи), где в нескольких местах встречаются конструкции примерно такого вида:
Для Каждого Док Из МассивПолученныхДокументовСтруктура Цикл
Для Каждого Рекв Из Док.Ссылка.Метаданные().Реквизиты Цикл
Если Док[Рекв.Имя] <> Док.Ссылка[Рекв.Имя] Тогда
Изменен = Истина;
КонецЕсли;
КонецЦикла;
КонецЦикла;
У франча нет программистов не специалистов, т.е., без сертификатов.
Но это же капец, нет?
Суть в том, что по самописному обмену (через web-сервис) приходят данные разных видов документов, заносятся в структуру, структура дополняется ссылками на существующие в базе документы и перед записью документов таким образом проверяется, изменились данные или нет.
То же самое делается для табличных частей.
И еще, уже после записи сделанные изменения сохраняются в регистр, где снова отрабатывают примерно такие же циклы, чтобы определить, что именно записать в регистр.
🤦♂️
(24) В здешнем случае, этот обмен - это самое критичное место во всей этой разработке.
Данных очень много, более 150 филиалов... Допускаю, конечно, что конечные разработчики, которым скинули часть задачи по ТЗ, этого не знали... И поэтому, тем, для кого важно качество своей работы, имеет смысл отучать себя писать так, в принципе...
Данных очень много, более 150 филиалов... Допускаю, конечно, что конечные разработчики, которым скинули часть задачи по ТЗ, этого не знали... И поэтому, тем, для кого важно качество своей работы, имеет смысл отучать себя писать так, в принципе...
(21)
Ну и главный вопрос. Если объект не поменялся по существу, то чего он в обмен попал и решил по веб сервису в приемник "прилететь"?
и перед записью документов таким образом проверяется, изменились данные или нет
Не проще ли работать не с данными, а с версиями. И не перед записью, а до того, как решил заполнить, полученными данными. В источнике же версия есть? Версия поменялась, значит надо перезаполнить, и, если захотелось, проверить что именно поменялось и поменялось ли :-).
Ну и главный вопрос. Если объект не поменялся по существу, то чего он в обмен попал и решил по веб сервису в приемник "прилететь"?
(26) Некоторые данные там загружаются консолидированно.
Т.е., в источнике берутся проводки без ненужных аналитик за определенный период и загружаются в документ приёмника. Тут сомнительно, но можно понять эту проверку (если бы не в таком виде).
А вот для чего это всё распространили на другие объекты, я пока не понимаю…
Т.е., в источнике берутся проводки без ненужных аналитик за определенный период и загружаются в документ приёмника. Тут сомнительно, но можно понять эту проверку (если бы не в таком виде).
А вот для чего это всё распространили на другие объекты, я пока не понимаю…
(28)
Консолидированная база и нужна для того, что-бы работать как приёмник.
Если уж прям очень хочется сравнивать и внутреннее содержание объектов, то проще рассчитать для каждого объекта какой-нибудь MD5 или подобное. При сохранении рассчитывать его и хранить его в объекте. При обмене передавать и его в том числе. Считай, что версия объекта с учетом содержания (без некоторых служебных реквизитов - например ВерсияОбъекта). Во входящих данных прилетит ссылка, MD5 в добавленном реквизите и всё содержимое объекта. А в ранее принятых данных этот MD5 уже есть. Если равны, то можно и не грузить и не бегать по всем реквизитам и по всем табличным частям, и что-то там проверять. Считайте, что была просто перезапись объекта в источнике без изменений.
Меня удивляет, что на уровне платформы этого не сделано. И при каждой записи объекта версия меняется как счетчик количества записываний.
А вот для чего это всё распространили на другие объекты, я пока не понимаю…
По моему проще принять тогда всё что пришло, чем что-то анализировать. На анализ времени уйдет вагон и тележка.
Консолидированная база и нужна для того, что-бы работать как приёмник.
Если уж прям очень хочется сравнивать и внутреннее содержание объектов, то проще рассчитать для каждого объекта какой-нибудь MD5 или подобное. При сохранении рассчитывать его и хранить его в объекте. При обмене передавать и его в том числе. Считай, что версия объекта с учетом содержания (без некоторых служебных реквизитов - например ВерсияОбъекта). Во входящих данных прилетит ссылка, MD5 в добавленном реквизите и всё содержимое объекта. А в ранее принятых данных этот MD5 уже есть. Если равны, то можно и не грузить и не бегать по всем реквизитам и по всем табличным частям, и что-то там проверять. Считайте, что была просто перезапись объекта в источнике без изменений.
Меня удивляет, что на уровне платформы этого не сделано. И при каждой записи объекта версия меняется как счетчик количества записываний.
(1)
Возвращаемые значения кэшируются, поэтому, если потом получить что-то еще "через точку", то запроса к базе не будет.
Более того, при таком подходе, во всяком случае в транзакции, 1С гарантирует целостность получаемых данных - чего не будет, если несколько раз вызвать ОбщегоНазначения.ЗначениеРеквизитаОбъекта.
Получается, что есть ряд случаев, когда это оптимальней, чем таскать по одному реквизиту.
Если оно вам не надо, то есть удобные методы БСП.
Отвечаю сразу на вопрос "а мы сразу кааак выберем, у нас и метод в БСП есть, все нужное" - не всегда это просто сделать, хотя бы с точки зрения читабельности кода.
Т.е. "точка" еще дает читаемость кода, если набор нужных реквизитов заранее не определен.
А так, да, вопроc из серии " а зачем в 1С goto?"
Вопросы: зачем вообще в платформу добавлена такая не оптимальная возможность обращения к реквизитам, через точку, где её можно использовать
Возвращаемые значения кэшируются, поэтому, если потом получить что-то еще "через точку", то запроса к базе не будет.
Более того, при таком подходе, во всяком случае в транзакции, 1С гарантирует целостность получаемых данных - чего не будет, если несколько раз вызвать ОбщегоНазначения.ЗначениеРеквизитаОбъекта.
Получается, что есть ряд случаев, когда это оптимальней, чем таскать по одному реквизиту.
Если оно вам не надо, то есть удобные методы БСП.
Отвечаю сразу на вопрос "а мы сразу кааак выберем, у нас и метод в БСП есть, все нужное" - не всегда это просто сделать, хотя бы с точки зрения читабельности кода.
Т.е. "точка" еще дает читаемость кода, если набор нужных реквизитов заранее не определен.
А так, да, вопроc из серии " а зачем в 1С goto?"
(1)
А зачем это добавлено? Для начала - это "совместимость" с 7.7, т.к. там не было SQL-подобных запросов, если не считать расширений для скульных баз. Ну и это реализация ОРМ, т.е. объектно-реляционной модели, т.к. этакого объекта с полным набором связанных данных для чтения. И только со временем, когда базы данных на 1С стали расти, на \то стали обращать так много внимания. В действительности, уже давно рекомендации 1С сводятся к тому, чтобы в запросе выбирать достаточное количество параметров, чтобы обработать их в последствии. Но если речь идет о работе с единичной ссылкой, то, возможно, в этом и нет никакой проблемы. Проблема начнется тогда, когда объектов станет неопределенное количество.
Вопросы:
Отлично!зачем вообще в платформу добавлена такая не оптимальная возможность обращения к реквизитам, через точку, где её можно использовать?
Обращение к реквизитам через точку в ссылке - это плохо. То, что оно кешируется - это плохая отмазка. В общем, не стоит так делать.
А зачем это добавлено? Для начала - это "совместимость" с 7.7, т.к. там не было SQL-подобных запросов, если не считать расширений для скульных баз. Ну и это реализация ОРМ, т.е. объектно-реляционной модели, т.к. этакого объекта с полным набором связанных данных для чтения. И только со временем, когда базы данных на 1С стали расти, на \то стали обращать так много внимания. В действительности, уже давно рекомендации 1С сводятся к тому, чтобы в запросе выбирать достаточное количество параметров, чтобы обработать их в последствии. Но если речь идет о работе с единичной ссылкой, то, возможно, в этом и нет никакой проблемы. Проблема начнется тогда, когда объектов станет неопределенное количество.
Есть ли какие-то простые и удобные способы получения значения одного реквизита, имея ссылку, кроме формирования текста запроса динамически?
Если это одна ссылка, то можно и через точку. Другое дело, что это может превратиться в какой-нить цикл, а это уже запрос в цикле, что считается плохо. И вообще, все зависит от контекста задачи. Если нужны несколько реквизитов одной ссылки, то можно через точку. Если же это разные ссылки, то лучше через запрос, при том отдельно написанный для этого вот случая. Ну и если это какой-то костыль временно-постоянный, то любой метод полезен, который создаст ценность за минимальное время.
(22)
Наверное, правильнее это назвать атавизмом.
Как минимум, поведение платформы в 8.х можно было изменить, сохранив такой синтаксис. ИМХО.
А зачем это добавлено? Для начала - это "совместимость" с 7.7, т.к. там не было SQL-подобных запросов, если не считать расширений для скульных баз.
Наверное, правильнее это назвать атавизмом.
Как минимум, поведение платформы в 8.х можно было изменить, сохранив такой синтаксис. ИМХО.
Если различных значений ссылки немного, а итераций в цикле много, то обращение через точку лучше, чем вызов ЗначениеРеквизитаОбъектов().
Например, в цикле 1000 итераций и есть конструкция Счет.Количественный. При ЗначениеРеквизитаОбъектов() будет 1000 обращений к данным, а при использовании точки счет закэшируется и в итерациях будет использоваться кэш.
Например, в цикле 1000 итераций и есть конструкция Счет.Количественный. При ЗначениеРеквизитаОбъектов() будет 1000 обращений к данным, а при использовании точки счет закэшируется и в итерациях будет использоваться кэш.
(34) И что? Трудно заранее один раз получить признаки необходимых счетов в соответствие (да, через ЗначениеРеквизитовОбъектов()) и при формировании проводок использовать данные из соответствия?
И как
И как
при использовании точки счет закэшируется
соотносится с по нескольким счетам
?
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот