Доклад хорош. Четко, без слов-паразитов, всяких "э-э", "а-а.." и тому подобного. Изложение звучит так, будто неоднократно отрепетировано - все по полкам, слушается легко. Забрел сюда случайно, к программированию в 1С не имею отношения, но считаю нужным отметить высокое качество подачи материала. Досмотрел до конца. Практически ничего не понял, но было интересно . Успехов в вашем деле!
Аналогично. Иногда пересматриваю старые видео этого канала, чтобы освежить память в каких-то нюансах или даже узнать какую-нибудь тонкость, но которую я не знал.
Не, ну это база!) На любом собесе спрашивают про методы оптимизации запросов. Я бы посмотрел по оптимизации запросов отдельное видео) Может, узнаю чего нового)
огромное спасибо. Коль вы уж коснулись тут еще темы индексации в запросах хотелось бы отдельное видео на эту тему. Ваши видео это кладезь знаний, для меня это всегда супер полезная выжимка фактов и отличная подача. Респект.
1. Зачем делать пакетный запрос? Можно же сразу объединить данные. 2. Почему не добавить артикул сразу в третьем запросе? Зачем его тянуть из первого? 3. Зачем обход результата в цикле? Нельзя сразу выгрузить результат запроса и загрузить его в таблицу без обхода?
тоже не понятно. даже если первый делать пакетом, то во втором сразу можно левым соединением и артикул получить. хорошо, что я больше не занимаюсь 1С. Но смотря такие видосы - думаешь правильно ли всё делал. какие-то излишние движения, которые путают.
Видимо, если брать артикул в третьем соединении через точку от ссылки на справочник, то это будет лишним левым соединением; а в первом запросе данные и так из этого справочника тянутся. Но места в оперативке будет занято больше, это да...на хранение всех ВТ.
Спасибо за комментарий) По поводу пакетного запроса: соединения с подзапросами и виртуальными таблицами - одна из причин неоптимальной работы запросов: its.1c.ru/db/metod8dev#content:5842:hdoc:vtable_join Метод Выгрузить() при большой таблице может привести к ошибке "Не хватает памяти", т.к. таблица значений создается в оперативной памяти. Обход выборки в этом плане оптимальнее) Но для маленьких таблиц Выгрузить() тоже можно использовать)
@@ironskills-1c ещё просьба. Очень было интересно, когда Вы анализировали запрос со стороны sql. Было бы здорово, если бы Вы рассказали как настраивать трассировку и как её анализировать.
Класс. Не знал про точку, что еще и к табличным частям запросы сформируются. Думал только один запрос сформируется на все реквизиты, а оно еще хуже оказывается :D
Вот почему так- когда смотрю ролики от айронскилл, так понимаю не только то, что в них показывают, а еще и приходит осознание, как БСП работает в других местах, как озарение наступает) классно)
Хорошее видео, хотелось бы еще таких видео, по типичным ошибкам новичков (и не только). Но есть один нюанс, заходишь в типовую конфигурацию и видишь там запрос в цикле)
Спасибо, правда давно это знал, но для новичков самое то. Можно было еще добавить что через БСП можно получить значение реквизита через ОбщегоНазначения.ЗначениеРеквизитаОбъекта, а так все супер как всегда 👍🏻👍🏻👍🏻
Да, тоже ожидал что в ролике про это уточнят, но тут в целом это и не требуется, да и использование функции в таком случае все равно будет равносильно запросу в цикле. Тогда уже лучше использовать ЗначениеРеквизитаОбъектов, где в качестве параметра передадим массив ссылок, тогда запрос выполнится единожды.
@@i_Carus92 ЗначениеРеквизитаОбъектов получит Соответствие в котором в цикле придется делать поиск. Соответствие, конечно, индексировано, но я бы все равно так не писал в данном кейсе. Ну а то, что ЗначениеРеквизитаОбъекта использовать в цикле нельзя - однозначно.
Большое спасибо! Про вредность запросов в цикле знал давно. Но вот, что обращение через точку это тоже запрос, а точнее еще несколько запросов - не знал. Буду перелопачивать отчетики с целью оптимизации!
2 вывода. Докладчик - умница, а 1с - козлы. При обращении через точку к реквизиту хватило бы одного запроса к SQL. То есть сами 1с заложили бомбу замедленного действия.
Наконец-то кто-то понятно объясняет стажёрам как нужно писать код в 1с. 15 лет в 1с. Лет 7 назад занимался код ревью на должности начальника отдела. На небольших базах гавнокод не заметен, а если у вас реально большая высоко нагруженная база, это всё жизненно необходимо. Так как сервер просто колом встаёт от такого когда, если он в том месте которое выполняется по 10 раз в секунду разными пользователями. Тогда время всех запросоа начинает увеличиваться и то что работало за 2с начинает работать за 10с плюс блокировки, и в какой-то момент достигается критическая масса гавнокода и бам! Всё встало. Поэтому код ревью нужен.
Спасибо большое за комментарий!) Да, подобные ошибки в коде на маленьких базах особо и незаметны, а вот на больших базах могут привести к большим проблемам)
Ну надо быть совсем недалеким, чтобы делать такой запрос остатков в цикле, за это надо руки отрывать и засовывать туда, откуда они растут. А вот зачем во втором варианте временные таблицы? когда можно сделать выборку по номенклатуре и левым соединением подтянуть остатки? На сервере будет еще меньше запросов, плюс СУБД сможет сама оптимизировать этот запрос. А если уж сильно хочется оптимизировать самим, то можно добавить условие на номенклатуру в сам регистр. Временные таблицы имеет смысл делать, если у нас сложная выборка, какая-то обработка этой выборки, и т.д. Хорошая подача материала, подписался. Кстати, мне попадался и контрпример, когда пришлось один запрос разбивать и делать много запросов в цикле, но это уже исключение из правил, связанное со сложностью запроса и огромным количеством выбираемых данных, там и временные таблицы не помогали.
Я знал, что нельзя писать запрос внутри цикла. Но для меня стало новостью, что получение реквизит через точку - тоже плохая идея. Спасибо за очень полезное видео!
Сразу возникает следующие выпросы: 1) Если мы выполняет следующий код: Номенклатура = Справочники.Номенклатура.НайтиПоКоду(Код); Массив.Добавить(Номенклатура.Артикул); Массив.Добавить(Номенклатура.Наименование); Тогда при обращении к каждому полю (Артикул и Наименование) будет выполняться по 3 запроса? 2) Чем хороши конструкции: НайтиПоКоду(), НайтиПоНаименованию(), НайтиПоНомеру() и т.д. -- они довольно лаконичны. Но получается, используя их, нам не стоит обращаться к полям полученной ссылки. Т.е. если в дальнейшем у нас появляется необходимость обращаться к полям полученной ссылки, лучше вместо данной конструкции сразу писать полноценный запрос, что увеличивает количество строк кода и снижает его читаемость. Есть возможность это как-то обойти не сильно увеличивая количество строк кода?
Если используется БСП, то "ОбщегоНазначения.ЗначениеРеквизитаОбъекта" - опять же в случае если не используется цикл, иначе лучше запросом дергать по списку
Посмотрите ролик на этом же канале про БСП, там упоминались процедуры "ПолучитьЗначениеРеквизита" и "ПолучитьЗначенияРеквизитов". Нужные вам реквизиты вы заранее получаете в структуру, к которой потом обращаетесь - вместо того, чтобы делать при каждом обращении все новые и новые запросы к базе данных
1) нет. Для этого все реквизиты и выбираются, чтобы не делать несколько запросов. Условно говоря, объект полностью загружается из БД при первом обращении через точку. И обращение к другим реквизитам уже не приводит к новым запросам.
Я конечно знал, что перебор в цикле это зло, но вот как делать временные таблицы в запросе знаю плохо, но теперь уже буду тренироваться. Огромное спасибо!
Скажу крамольную мысль, но запрос в цикле - не всегда плохо. Все зависит от быстродействия и объема выбираемых данных. Долгое время в самописной конфигурации страдали от огромного запроса, который все усложнялся, не работал как надо, и никто не понимал полностью что он делает. Переписав участок кода на запросы в цикле, скорость резко выросла, читаемость кода улучшилась. Другой пример - выбирался огромный объем данных, выгружался в таблицу для обработки. Иногда коду не хватало памяти. Пришлось обрабатывать данные по частям, для чего пришлось делать запрос в цикле. Так что просто утверждение, что запрос в цикле - всегда зло, не верное. Нужно оценивать оптимальность и быстродействие.
Когда заказчик мудрит и на ходу меняет задачу, то я часто именно так намеренно делаю. Хрен с ней с производительностью, но с отладкой в разы меньше заморочек.
Виртуальные таблицы не надо индексировать (если они уж не совсем гигантские). Если вы делаете индексирование на ВТ, она "сбрасывается на винт" на сервере. Без индекса ВТ "живет" в оперативке.
Спасибо за комментарий) Да, с индексированием тут все действительно не однозначно. Даже при большой таблице индексирование может не дать ускорения) Есть стандарт #std777, где фирма 1С не рекомендует индексировать маленькие таблицы (менее 1000 записей): its.1c.ru/db/v8std/content/777/hdoc
1.когда я был начинающим, первое, что мне сказали- не пиши так.и я не писал. кому-то не говорят, что-ли?)) (это про запросы в цикле) 2.индексы. на 3 тысячи строк. ты серьёзно?) (не умею профайлером пользоваться, но почти уверен, что он и добавление индексов может показать). 3.просто загрузить ТЗ в ТЧ религия не позволяет? обязательно цикл делать? мда..антиреклама какая-то) в целом- очень информативно и по делу, без воды. дикция и манера речи на высшем уровне. красава.
1. Да, говорят не всем про это, либо не все запоминают) Запросы в цикле встречаются повсеместно на проектах)) 2. Это учебный пример, таблица может в общем случае быть сильно больше 3 тыс. строк ;) 3. На экзамене 1С:Специалист за такое будет минус балл: disk.yandex.com/i/IEqdAn6Z0ubwOg
Вот точно так были написаны подключаемые обработки для обмена с планшетами у популярного продукта мобильной торговли Агент+. Обмены с Эвотором написаны аналогично.
Спасибо за лайфхаки, как сделать нечто плохое, если тебя увольняют ))) надеюсь не пригодится! Даже в голову не приходило такое страшное писать за 10 лет
Наверное большая часть ваших подписчиков это знает, так как это прям база. Лайк конечно поставил, но хотелось бы темы по зрелищней о том как не стоит писать.
В некоторых случая без запросов в цикле никак...пример, отправка данных на сайт интернет магазина. Если делать гиганскую выборку "всего отправляемого" происходит вылет по оперативной памяти. Поэтому инфа сначала дробится на части, а потом запросами в цикле получается и отправляется
1С не ставить табу на запросы в цикле. Если задача требует такого подхода, то минимальным обязательным требованием является создание запроса за рамками цикла.
А почему 1С через точку запрашивает из БД всю портянку реквизитов? Я программист простой, воспитанный в духе "Доступно и всерьез". Почему вместо простого и интуитивно понятного получения реквизита через точку я вынужден пользоваться костылем получения реквизита объекта из БСП ?
А кто-нить проверял скорость выполнения "Номенклатура.Артикул" точно ли больше чем "ПолучитьСвойство(Номенклатура, "Артикул")" ? Просто у нас куча действий производится при "входе" в функцию, внутри функции несколько выделений памяти под запрос и под структуру, там еще есть всякие условия и т.д. А 1с у нас интерпретационный язык программирования. Получается хоть какая-то выгода в загрузке сервера или времени выполнения?
У нас бухгалтерша была Надя. Я говорю ей: код написан неоптимально, надо переписать, а то он будет делаться долго. На что она мне отвечает: "Главное не руками делать отчет" 😆
А бывает и так: оптимизируешь какой-то код так, что он начинает выполняться не 30 секунд, а 1 секунду, а от пользователя получаешь: "а почему оно теперь ничего не делает?".
Возможно мой вопрос покажется нелепым, но я только учусь, а зачем при выборе остатков мы делаем подзапрос и выбираем только номенклатуру из первой таблицы, ведь при левом соединении и так в итоговую таблицу попадут остатки только по номенклатуре из первой таблицы?
В стандартах 1С не рекомендуется делать соединения с виртуальными таблицами. Сначала нужно поместить данные виртуальной таблицы во временную, а потом временную соединять.
отличное наглядное пояснение, можно сразу кидать ссылку непонимающим. Но это фигня. Я уже столкнулся с вложенными подзапросами, обращающимися ТЧ документа за все время учета, временныем таблицами с запросом обращения к регистру, у которого в условии мало того что куча вложенных Выбор-Когда-Тогда, так еще и это: Когда Не Таблица.Серия ЕСТЬ NULL Тогда НЕ Таблица.Серия В (Выбрать ...), где вложенный запрос - это этот же из временной таблицы, только с доп условием Когда-Тогда в секции где... И все это в одной обработке, где таких пакетов запросов 4 и различаются они лишь незначительно условиями. а еще есть в ней 2 одинаковых пакета запросов, которые отличаются 2мя доп реквизитами и по факту объединяют первые 4 пакета запросов. И каждый пакет формируется по всей базе заново, тк человек наверно не знает МВТ. Если что, по времени обработка отрабатывает на сервере минуты 3-5. На ПК в файловой копии минут 50. А после недавнего обновления, оптимизация всего этого садо-мазо при трансляции в скуль стала хуже и некоторые вложенные запросы начали выполняться так как и должны: в цикле, из за чего обработка работает на клиент-серверной базе 1.5 часа. Поэтому мне уже как-то безразлично разыменование через точку. И вообще, я не знаю особо конфигурацию и сгорел в попытках разобрать все это дерьмо и поисках ответов на вопросы зачем и нахрена. Но я по прежнему не готов последовать совету "не трож, оно работает" коллег прекрасно зная что "оно меня сожрет". Сорян за крик души, я новичок в 1с, но не думал, что есть люди настолько новичковее меня.
А зачем нужно было в цикле добавлять по одной строке, если можно было результат запроса выгрузить и загрузить в табличную часть. Это дало бы еще больший прирост скорости
Зачем вообще столько временных таблиц? Никто из тех кто это показывает, не говорит, что они пишутся на диск, еще и индексы под них создаются. А это тоже время. В данном случае вполне хватило бы одной ВТ.
Академически все верно.....Но, я старый программист, озвучу одну крамольную истину(не пинайте больно). Если код приемлемо работает и, в принципе, заказчика устраивает - ДА ХРЕН БЫ С НИМ!!! )))
Постоянно правлю такие поделки и проблемы связанные с ними, спасибо тебе добрый человек, пока есть ты и такие как ты работа у разработчиков 1С не закончится никогда.
@@Антон-з5к7р не учитываете повышенные риски правки старого кривого недокументированного кода - вы "исправите" (как вам кажется), а от этого кода зависит ещё куча такого же кривого кода, о котором вы не догадываетесь и получится классическое "у нас тут всё работало, вы пришли, что-то поменяли и у нас теперь НИЧЕГО не работает!! сделайте что-нибудь! вы поломали нам всё!" в старых кривых конфигурациях нужно триста раз подумать и всё взвесить прежде чем хоть что-то "улучшать" если что с 1С я 25 лет из них лет 15 как проджект менеджер и архитектор
@@Антон-з5к7рЧеловек прямо написал что код рабочий и заказчика устраивает и проблем с ним не возникает. Проблема это когда заказчика не устраивает ))))) А заказчика частенько не устраивает и очень-очень оптимальный код, если этот код поставленную задачу не решает.
@@alexandrshulgin82 Изначально делать лучше хорошо, но если досталось такое наследство от предыдущего франчайзера, то я исправлю только там где это критично. А работающий запрос в цикле, например по справочнику организаций оставлю как есть и трогать не буду
Есть еще много много боли от кода настоящих талантливых программистов. Запросы в цикле - это так. Классика жанра. Например есть замечательные кодеры, которые вводят других в заблуждение не так называя переменные или реквизиты. Условные операторы лесенкой. Лепят все в одной процедуре, когда ее надо дробить и прочее и прочее и прочее... Можно целый выпуск сънять о том, как не надо кодить.
Проблема обращения через точку - не проблема программиста, а только кривых рук разработчиков платформы... Если я явно указываю через точку нужный мне реквизит, за каким они достают все поля объекта? Почему бы не сделать как положено - вытаскивать только нужный параметр через точку... Чтобы все знали про БСП?.. Чтобы запутать врагов?... неясно...
Тут идея скорее всего была такая: "давайте будем получать, на всякий пожарный, сразу все данные, потому что разработчик может написать так: Артикул = Номенклатура.Артикул; Код = Номенклатура.Код; и тогда сильно вырастет количество запросов к базе" :)
А вот у меня вопрос - как изменится время выполнения, если не помещать остатки из регистра в вт, а сразу во втором пакете соединять вт_товары с выборкой из регистра?
Быстрее будет не пакетным запросом, а просто левым срединением к виртуальной таблице. Таблица ьез параметра, значит просто приклеит таблицу итогов, без всяких заморочек
Спасибо, хотя и не узнал нового, вопрос, в данном примере если заменить предварительную выборку элементов с помещением в ВТ на единый запрос с соединением первой таблицы , как изменилась бы скорость? Свой ответ знаю, интересен ответ других людей и Автора
Соединение с подзапросами, а также с виртуальными таблицами - одна из причин неоптимальной работы запросов: its.1c.ru/db/metod8dev#content:5842:hdoc:vtable_join
@@ironskills-1cсоздание виртуальной таблицы - дорогая операция. Классически задача решается через левое соединение. Все преимущество вирт.таблиц при указании фильтра превратится в тыкву при размере, скажем, 100к записей, а при 100к*100к будет совсем грустно, в то время как левому соединению будет это безразлично.
В данном конкретном случае убрал бы цикл к чертям. Таблица.Загрузить(Запрос.Выполнить().Выгрузить()). И это кстати и приучает всё и всегда получать сразу в одном запросе.
Да, но при большом объеме данных метод Выгрузить() может привести к нехватке памяти, т.к. данные загружаются в оперативную память) Через выборку - более щадящий режим, хоть и кода больше писать надо)
Эммм только начал изучать, и у меня возник вопрос зачем цикл для заполнения табличной части, разве нет способа заполнить скажем так ТаблицаюЗаполнить(ВыборкаТовары), ну это как пример, думаю что долждны быть какието еще параметры. скажем сотриторва в табличной части по наименованию.
В этом как раз и преимущество подачи материала от Ивана - Он не перегружает и не вываливает разом все свои знания на новичков. Про ЗаполнитьЗначенияСвойств у него на курсе есть отдельный блок.
Спасибо за ролик, некоторые полезные вещи подчерпнул. Только один вопрос. Зачем создавать вторую временную таблицу для выборки регистра? Почему нельзя сразу соединить Справочник.Товары с регистром остатков в одном запросе?
Чтобы проиндексировать поле Номенклатура. Тогда итоговый запрос будет выполняться в разы быстрее. Хотя можно поставить ее с левой стороны, а справа первую проиндексированную таблицу. Но это надо проверять. И желательно на больших объемах.
Потому что если виртуальная таблица собирает данные из нескольких физических таблиц, то на уровне SQL это реализуется как подзапрос к этим таблицам и в нашем запросе получается соединение с подзапросом, которое очень сильно зависит от разных условий(актуальности статистики, типа СУБД и т.д.) и может работать нестабильно, поэтому лучше выбрать данные регистра во временную таблицу и проиндексировать её.
как уже отмечал ранее, у ваших роликов есть огромный недостаток - они очень редко выходят.
очень понятно, очень наглядно, очень познавательно.
потому что это средство привлечение на курсы, а не курс. спасибо что хоть чем-то делится действенным
@@ser.sinyavin Причем то чем он делится, это не "действенное" а унылая рутина, про которую можно почитать в любой желтой книжке по разработке 1с
@@ИгорьСергеевич-е9э ну хзхз. Его набор шаблонов доп. обработок прям для меня палочка-выручалочка. Очень часто пользуюсь.
@@TRIALEX3 где взять эти шаблоны?
@@Trixter-kh9tb в одном из видео на канале. Что то про доп обработки в названии.
Доклад хорош. Четко, без слов-паразитов, всяких "э-э", "а-а.." и тому подобного. Изложение звучит так, будто неоднократно отрепетировано - все по полкам, слушается легко.
Забрел сюда случайно, к программированию в 1С не имею отношения, но считаю нужным отметить высокое качество подачи материала. Досмотрел до конца. Практически ничего не понял, но было интересно .
Успехов в вашем деле!
Спасибо огромное за комментарий)
Блин, видео вообще огонь! Словно мед в уши, кода ревью по 1С в ютубе нет, пожалуйста, продолжайте делать дальше такие видосы)
Спасибо) Будем развивать эту тему)
ISNULL Иван!! ISNULL ты открыл мне глаза, сколько же я страдал с этим естьnull
Работаю программистом 1с около 5 лет. хоть и знал о таких моментах, но все же посмотреть было очень интересно и познавательно! Спасибо!
Аналогично. Иногда пересматриваю старые видео этого канала, чтобы освежить память в каких-то нюансах или даже узнать какую-нибудь тонкость, но которую я не знал.
Спасибо за комментарий)
Не, ну это база!)
На любом собесе спрашивают про методы оптимизации запросов.
Я бы посмотрел по оптимизации запросов отдельное видео)
Может, узнаю чего нового)
огромное спасибо. Коль вы уж коснулись тут еще темы индексации в запросах хотелось бы отдельное видео на эту тему. Ваши видео это кладезь знаний, для меня это всегда супер полезная выжимка фактов и отличная подача. Респект.
Спасибо большое! :) При индексы обязательно сделаем видео)
Спасибо! Знал, что обращение к реквизитам через точку - bad practices, но впервые получил превосходное и внятное объяснение, почему.
Доступно и наглядно были показаны ошибки. А также сравнительная разница, выполнения обработки между двумя вариантами. Супер.
Лучшая подача материала. Спасибо!
1. Зачем делать пакетный запрос? Можно же сразу объединить данные.
2. Почему не добавить артикул сразу в третьем запросе? Зачем его тянуть из первого?
3. Зачем обход результата в цикле? Нельзя сразу выгрузить результат запроса и загрузить его в таблицу без обхода?
тоже не понятно. даже если первый делать пакетом, то во втором сразу можно левым соединением и артикул получить. хорошо, что я больше не занимаюсь 1С. Но смотря такие видосы - думаешь правильно ли всё делал. какие-то излишние движения, которые путают.
Видимо, если брать артикул в третьем соединении через точку от ссылки на справочник, то это будет лишним левым соединением; а в первом запросе данные и так из этого справочника тянутся. Но места в оперативке будет занято больше, это да...на хранение всех ВТ.
Спасибо за комментарий) По поводу пакетного запроса: соединения с подзапросами и виртуальными таблицами - одна из причин неоптимальной работы запросов: its.1c.ru/db/metod8dev#content:5842:hdoc:vtable_join
Метод Выгрузить() при большой таблице может привести к ошибке "Не хватает памяти", т.к. таблица значений создается в оперативной памяти. Обход выборки в этом плане оптимальнее)
Но для маленьких таблиц Выгрузить() тоже можно использовать)
Отличное видео. 👍
Пожалуйста, можно рубрику "не пиши так" почаще?)
Поддерживаю! Классная рубрика будет, если введете на постоянной основе. Иван, спасибо!
Классная идея, спасибо, будем развивать эту тему)
@@ironskills-1c ещё просьба. Очень было интересно, когда Вы анализировали запрос со стороны sql. Было бы здорово, если бы Вы рассказали как настраивать трассировку и как её анализировать.
Спасибо, весьма познавательно и наглядно.
Спасибо! Как всегда всё понятно и очень наглядно.
Спасибо большое, Иван!
Класс. Не знал про точку, что еще и к табличным частям запросы сформируются. Думал только один запрос сформируется на все реквизиты, а оно еще хуже оказывается :D
Вот почему так- когда смотрю ролики от айронскилл, так понимаю не только то, что в них показывают, а еще и приходит осознание, как БСП работает в других местах, как озарение наступает) классно)
Как обычно, всё до делу! Ребята, у Ивана должна быть личная жизнь и время на заработок!
Спасибо! Продолжайте!
Классная подача материала, толково и легко смотрится.
Полезно! Побольше бы таких видео.
Нужно сделать ещё видео с такими же примера с индексацией.
Этот контент надо рекомендовать всем программистам, а не только 1с
Как всегда супер! Спасибо Иван!
Спасибо, наглядно и познавательно
Хорошее видео, хотелось бы еще таких видео, по типичным ошибкам новичков (и не только).
Но есть один нюанс, заходишь в типовую конфигурацию и видишь там запрос в цикле)
Да ну, вроде в типовых там чистейший код. А что за конфигурация можно узнать?
@@MrTorfable Точно видел в рознице, правда старой 2.2 и еще, вроде, в УНФ
близко нет@@MrTorfable
@@Dima-ko6ub да, тоже нашёл несколько странных строчек кода в типовой конфигурации
@@MrTorfable с опытом найдешь еще больше))
Спасибо, правда давно это знал, но для новичков самое то. Можно было еще добавить что через БСП можно получить значение реквизита через ОбщегоНазначения.ЗначениеРеквизитаОбъекта, а так все супер как всегда 👍🏻👍🏻👍🏻
Да, тоже ожидал что в ролике про это уточнят, но тут в целом это и не требуется, да и использование функции в таком случае все равно будет равносильно запросу в цикле. Тогда уже лучше использовать ЗначениеРеквизитаОбъектов, где в качестве параметра передадим массив ссылок, тогда запрос выполнится единожды.
@@i_Carus92 ЗначениеРеквизитаОбъектов получит Соответствие в котором в цикле придется делать поиск. Соответствие, конечно, индексировано, но я бы все равно так не писал в данном кейсе. Ну а то, что ЗначениеРеквизитаОбъекта использовать в цикле нельзя - однозначно.
Ура!!! Новое видео, спасибо большое! :)
Спасибо большон, очень годный выпуск, хочется еще!
Шикарно. Как раз делаю обработку точь в точь 😅 в принципе знал про табу на запросы в циклах, но теперь супер подробно все понял)) спс)
Большое спасибо! Про вредность запросов в цикле знал давно. Но вот, что обращение через точку это тоже запрос, а точнее еще несколько запросов - не знал. Буду перелопачивать отчетики с целью оптимизации!
Спасибо, друг! Очень наглядно.
Идеальное объяснение!!!🎉
Наглядно, познавательно. Спасибо :)
Иван, привет!
Спасибо тебе за твой труд!
Я твой фанат.)
Спасибо)
Как новичку в программировании, такие кейсы очень полезны. Спасибо!
2 вывода. Докладчик - умница, а 1с - козлы. При обращении через точку к реквизиту хватило бы одного запроса к SQL. То есть сами 1с заложили бомбу замедленного действия.
И в чем же 1с козлы?)
Сделай пожалуйста полноценный курс по оптимизации кода и в целом 1с.
Спасибо ! как всегда - Шикарно !
Иван, как всегда супер подробно 👍.
Я морально пострадал от запроса в цикле
ИМХО, если команда разработки небольшая, то в конфигураторе работать удобнее)
Отлично! Хоть и все это знаю и это понятно, но все равно - Спасибо
Спасибо!
Спасибо, Иван! Заставка 🔥
Спасибо)
Наконец-то кто-то понятно объясняет стажёрам как нужно писать код в 1с. 15 лет в 1с. Лет 7 назад занимался код ревью на должности начальника отдела. На небольших базах гавнокод не заметен, а если у вас реально большая высоко нагруженная база, это всё жизненно необходимо. Так как сервер просто колом встаёт от такого когда, если он в том месте которое выполняется по 10 раз в секунду разными пользователями. Тогда время всех запросоа начинает увеличиваться и то что работало за 2с начинает работать за 10с плюс блокировки, и в какой-то момент достигается критическая масса гавнокода и бам! Всё встало. Поэтому код ревью нужен.
Спасибо большое за комментарий!) Да, подобные ошибки в коде на маленьких базах особо и незаметны, а вот на больших базах могут привести к большим проблемам)
Ну надо быть совсем недалеким, чтобы делать такой запрос остатков в цикле, за это надо руки отрывать и засовывать туда, откуда они растут. А вот зачем во втором варианте временные таблицы? когда можно сделать выборку по номенклатуре и левым соединением подтянуть остатки? На сервере будет еще меньше запросов, плюс СУБД сможет сама оптимизировать этот запрос. А если уж сильно хочется оптимизировать самим, то можно добавить условие на номенклатуру в сам регистр. Временные таблицы имеет смысл делать, если у нас сложная выборка, какая-то обработка этой выборки, и т.д. Хорошая подача материала, подписался. Кстати, мне попадался и контрпример, когда пришлось один запрос разбивать и делать много запросов в цикле, но это уже исключение из правил, связанное со сложностью запроса и огромным количеством выбираемых данных, там и временные таблицы не помогали.
Кто бы ещё разрабам типовых конфигураций 1С рассказал, как не надо писать...
Спасибо. Знал, что так нельзя делать, но до конца не понимал почему.
Приятно наблюдать то как растет аудитория и телеграмм группа, а мой путь начинался с Отчеты за 14 дней)
Успехов, и больших свершений
Спасибо огромное!)
мне кажется информация, на уровне топ. и подача и полезность.
Вижу новый видос, автоматом ставлю лайк и перехожу к просмотру😅👍
Я знал, что нельзя писать запрос внутри цикла. Но для меня стало новостью, что получение реквизит через точку - тоже плохая идея. Спасибо за очень полезное видео!
Сразу возникает следующие выпросы:
1) Если мы выполняет следующий код:
Номенклатура = Справочники.Номенклатура.НайтиПоКоду(Код);
Массив.Добавить(Номенклатура.Артикул);
Массив.Добавить(Номенклатура.Наименование);
Тогда при обращении к каждому полю (Артикул и Наименование) будет выполняться по 3 запроса?
2) Чем хороши конструкции: НайтиПоКоду(), НайтиПоНаименованию(), НайтиПоНомеру() и т.д. -- они довольно лаконичны. Но получается, используя их, нам не стоит обращаться к полям полученной ссылки. Т.е. если в дальнейшем у нас появляется необходимость обращаться к полям полученной ссылки, лучше вместо данной конструкции сразу писать полноценный запрос, что увеличивает количество строк кода и снижает его читаемость.
Есть возможность это как-то обойти не сильно увеличивая количество строк кода?
Если используется БСП, то "ОбщегоНазначения.ЗначениеРеквизитаОбъекта" - опять же в случае если не используется цикл, иначе лучше запросом дергать по списку
Посмотрите ролик на этом же канале про БСП, там упоминались процедуры "ПолучитьЗначениеРеквизита" и "ПолучитьЗначенияРеквизитов". Нужные вам реквизиты вы заранее получаете в структуру, к которой потом обращаетесь - вместо того, чтобы делать при каждом обращении все новые и новые запросы к базе данных
@@helmetson652 , спасибо, посмотрел эти функции. В них создаётся запрос исходя из метаданных ссылки и выполняется запрос с получением всех реквизитов.
@@sergeyn2956 , спасибо!
1) нет. Для этого все реквизиты и выбираются, чтобы не делать несколько запросов. Условно говоря, объект полностью загружается из БД при первом обращении через точку. И обращение к другим реквизитам уже не приводит к новым запросам.
Круто Наглядно!!! Класс
Спасибо, полезно!
Я конечно знал, что перебор в цикле это зло, но вот как делать временные таблицы в запросе знаю плохо, но теперь уже буду тренироваться. Огромное спасибо!
Скажу крамольную мысль, но запрос в цикле - не всегда плохо. Все зависит от быстродействия и объема выбираемых данных. Долгое время в самописной конфигурации страдали от огромного запроса, который все усложнялся, не работал как надо, и никто не понимал полностью что он делает. Переписав участок кода на запросы в цикле, скорость резко выросла, читаемость кода улучшилась. Другой пример - выбирался огромный объем данных, выгружался в таблицу для обработки. Иногда коду не хватало памяти. Пришлось обрабатывать данные по частям, для чего пришлось делать запрос в цикле. Так что просто утверждение, что запрос в цикле - всегда зло, не верное. Нужно оценивать оптимальность и быстродействие.
ммм Запрос в цикле...мой любимый инструмент в старых конфигурациях)))Сейчас маленько поумнел - стараюсь так больше не делать) Спасибо за видео!
Когда заказчик мудрит и на ходу меняет задачу, то я часто именно так намеренно делаю. Хрен с ней с производительностью, но с отладкой в разы меньше заморочек.
Виртуальные таблицы не надо индексировать (если они уж не совсем гигантские).
Если вы делаете индексирование на ВТ, она "сбрасывается на винт" на сервере. Без индекса ВТ "живет" в оперативке.
виртуальные таблицы лучше индексировать. потому что на больших объемах - это просто необходимо, а на маленьких - этими затратами можно пренебречь
Большой объем ВТ это сколько??@@TresModiosVir
Спасибо за комментарий) Да, с индексированием тут все действительно не однозначно. Даже при большой таблице индексирование может не дать ускорения)
Есть стандарт #std777, где фирма 1С не рекомендует индексировать маленькие таблицы (менее 1000 записей): its.1c.ru/db/v8std/content/777/hdoc
офигеть, спасибо
1.когда я был начинающим, первое, что мне сказали- не пиши так.и я не писал. кому-то не говорят, что-ли?)) (это про запросы в цикле)
2.индексы. на 3 тысячи строк. ты серьёзно?) (не умею профайлером пользоваться, но почти уверен, что он и добавление индексов может показать).
3.просто загрузить ТЗ в ТЧ религия не позволяет? обязательно цикл делать?
мда..антиреклама какая-то)
в целом- очень информативно и по делу, без воды. дикция и манера речи на высшем уровне. красава.
1. Да, говорят не всем про это, либо не все запоминают) Запросы в цикле встречаются повсеместно на проектах))
2. Это учебный пример, таблица может в общем случае быть сильно больше 3 тыс. строк ;)
3. На экзамене 1С:Специалист за такое будет минус балл: disk.yandex.com/i/IEqdAn6Z0ubwOg
Блин, "ну, это же двоечка для девочек". Практически самые основы.
Спасибо большое, Иван! Классный ролик, отличная подача - 👍! Непонятно, то ли футболка такая, то ли качаццо начал?)))
Вот точно так были написаны подключаемые обработки для обмена с планшетами у популярного продукта мобильной торговли Агент+. Обмены с Эвотором написаны аналогично.
Круто! Хорошо было бы побольше делать такое видео
Спасибо за лайфхаки, как сделать нечто плохое, если тебя увольняют ))) надеюсь не пригодится! Даже в голову не приходило такое страшное писать за 10 лет
Иван, подскажите пожалуйста, по работе с sql профайлером у вас на канале есть видео?
пока что нету(
@@ironskills-1c жаль, спасибо за ответ )
Наверное большая часть ваших подписчиков это знает, так как это прям база. Лайк конечно поставил, но хотелось бы темы по зрелищней о том как не стоит писать.
Будем записывать ещё на эту тему))
В некоторых случая без запросов в цикле никак...пример, отправка данных на сайт интернет магазина. Если делать гиганскую выборку "всего отправляемого" происходит вылет по оперативной памяти. Поэтому инфа сначала дробится на части, а потом запросами в цикле получается и отправляется
Спасибо за комментарий) Да, действительно, есть задачи, где запрос в цикле используется, главное, чтобы это был осознанный выбор разработчика)
1С не ставить табу на запросы в цикле. Если задача требует такого подхода, то минимальным обязательным требованием является создание запроса за рамками цикла.
А почему 1С через точку запрашивает из БД всю портянку реквизитов? Я программист простой, воспитанный в духе "Доступно и всерьез". Почему вместо простого и интуитивно понятного получения реквизита через точку я вынужден пользоваться костылем получения реквизита объекта из БСП ?
А кто-нить проверял скорость выполнения "Номенклатура.Артикул" точно ли больше чем "ПолучитьСвойство(Номенклатура, "Артикул")" ?
Просто у нас куча действий производится при "входе" в функцию, внутри функции несколько выделений памяти под запрос и под структуру, там еще есть всякие условия и т.д. А 1с у нас интерпретационный язык программирования.
Получается хоть какая-то выгода в загрузке сервера или времени выполнения?
Спасибо, было полезно. Есть ли у postgreSQL аналог профилера sql server? Какие посоветуете? У нас база на постриге в системе линукс
У нас бухгалтерша была Надя. Я говорю ей: код написан неоптимально, надо переписать, а то он будет делаться долго. На что она мне отвечает: "Главное не руками делать отчет" 😆
😀
А бывает и так: оптимизируешь какой-то код так, что он начинает выполняться не 30 секунд, а 1 секунду, а от пользователя получаешь: "а почему оно теперь ничего не делает?".
Возможно мой вопрос покажется нелепым, но я только учусь, а зачем при выборе остатков мы делаем подзапрос и выбираем только номенклатуру из первой таблицы, ведь при левом соединении и так в итоговую таблицу попадут остатки только по номенклатуре из первой таблицы?
Чтобы не получать остатки по всей номенклатуре. Чем больше таблица остатков, тем дольше будет происходить ее соединение.
В стандартах 1С не рекомендуется делать соединения с виртуальными таблицами. Сначала нужно поместить данные виртуальной таблицы во временную, а потом временную соединять.
@@ВладБалабанов-е3ы Понял, спасибо
Всё так! Только про уничтожение временных таблиц не рассказал.
отличное наглядное пояснение, можно сразу кидать ссылку непонимающим.
Но это фигня. Я уже столкнулся с вложенными подзапросами, обращающимися ТЧ документа за все время учета, временныем таблицами с запросом обращения к регистру, у которого в условии мало того что куча вложенных Выбор-Когда-Тогда, так еще и это: Когда Не Таблица.Серия ЕСТЬ NULL Тогда НЕ Таблица.Серия В (Выбрать ...), где вложенный запрос - это этот же из временной таблицы, только с доп условием Когда-Тогда в секции где... И все это в одной обработке, где таких пакетов запросов 4 и различаются они лишь незначительно условиями. а еще есть в ней 2 одинаковых пакета запросов, которые отличаются 2мя доп реквизитами и по факту объединяют первые 4 пакета запросов. И каждый пакет формируется по всей базе заново, тк человек наверно не знает МВТ. Если что, по времени обработка отрабатывает на сервере минуты 3-5. На ПК в файловой копии минут 50. А после недавнего обновления, оптимизация всего этого садо-мазо при трансляции в скуль стала хуже и некоторые вложенные запросы начали выполняться так как и должны: в цикле, из за чего обработка работает на клиент-серверной базе 1.5 часа.
Поэтому мне уже как-то безразлично разыменование через точку. И вообще, я не знаю особо конфигурацию и сгорел в попытках разобрать все это дерьмо и поисках ответов на вопросы зачем и нахрена. Но я по прежнему не готов последовать совету "не трож, оно работает" коллег прекрасно зная что "оно меня сожрет". Сорян за крик души, я новичок в 1с, но не думал, что есть люди настолько новичковее меня.
Спасибо что поделились опытом) Да, в чужом коде часто можно встретить "интересные" решения))
Здравствуйте! Какой Шрифт используете в конфигурации?
А зачем нужно было в цикле добавлять по одной строке, если можно было результат запроса выгрузить и загрузить в табличную часть. Это дало бы еще больший прирост скорости
не дало бы
Спасибо ! все как всегда очень доходчиво без лишней воды. из любоавтства - почему нельзя сделать сразу без Временных таблиц ?
Отлично и наглядно, спаибо. А есть видео по настройке трассировки в профайлере?
Пишите по старому, чтобы бухгалтер смогла сходить и попить чаю!!
Иначе она будет все время работать и кое-кого ненавидеть.
Да, с бухгалтерами надо дружить :)
Зачем вообще столько временных таблиц? Никто из тех кто это показывает, не говорит, что они пишутся на диск, еще и индексы под них создаются. А это тоже время. В данном случае вполне хватило бы одной ВТ.
Видимо потому что разница в 3мс с вашим вариантом при этом объеме данных уже не имеет значения.
Не пишутся они на диск. На диск сброс может быть только если памяти не хватает, но таким образом и при сортировке таблица может на диск сброситься
Академически все верно.....Но, я старый программист, озвучу одну крамольную истину(не пинайте больно). Если код приемлемо работает и, в принципе, заказчика устраивает - ДА ХРЕН БЫ С НИМ!!! )))
Постоянно правлю такие поделки и проблемы связанные с ними, спасибо тебе добрый человек, пока есть ты и такие как ты работа у разработчиков 1С не закончится никогда.
@@Антон-з5к7р не учитываете повышенные риски правки старого кривого недокументированного кода - вы "исправите" (как вам кажется), а от этого кода зависит ещё куча такого же кривого кода, о котором вы не догадываетесь и получится классическое "у нас тут всё работало, вы пришли, что-то поменяли и у нас теперь НИЧЕГО не работает!! сделайте что-нибудь! вы поломали нам всё!"
в старых кривых конфигурациях нужно триста раз подумать и всё взвесить прежде чем хоть что-то "улучшать"
если что с 1С я 25 лет из них лет 15 как проджект менеджер и архитектор
@@Антон-з5к7рЧеловек прямо написал что код рабочий и заказчика устраивает и проблем с ним не возникает. Проблема это когда заказчика не устраивает ))))) А заказчика частенько не устраивает и очень-очень оптимальный код, если этот код поставленную задачу не решает.
можно делать и так - а можно хорошо, а если на время работы это не влияет, то зачем делать не хорошо?
@@alexandrshulgin82 Изначально делать лучше хорошо, но если досталось такое наследство от предыдущего франчайзера, то я исправлю только там где это критично. А работающий запрос в цикле, например по справочнику организаций оставлю как есть и трогать не буду
Спасибо
Есть еще много много боли от кода настоящих талантливых программистов. Запросы в цикле - это так. Классика жанра. Например есть замечательные кодеры, которые вводят других в заблуждение не так называя переменные или реквизиты. Условные операторы лесенкой. Лепят все в одной процедуре, когда ее надо дробить и прочее и прочее и прочее... Можно целый выпуск сънять о том, как не надо кодить.
Да, отличная идея) Спасибо большое за комментарий)
Проблема обращения через точку - не проблема программиста, а только кривых рук разработчиков платформы... Если я явно указываю через точку нужный мне реквизит, за каким они достают все поля объекта? Почему бы не сделать как положено - вытаскивать только нужный параметр через точку... Чтобы все знали про БСП?.. Чтобы запутать врагов?... неясно...
Тут идея скорее всего была такая:
"давайте будем получать, на всякий пожарный, сразу все данные, потому что разработчик может написать так:
Артикул = Номенклатура.Артикул;
Код = Номенклатура.Код;
и тогда сильно вырастет количество запросов к базе" :)
@@ironskills-1c так это идея или это так и работает? Что говорит документация?))
Наглядненько.
А вот у меня вопрос - как изменится время выполнения, если не помещать остатки из регистра в вт, а сразу во втором пакете соединять вт_товары с выборкой из регистра?
Делал делаю и буду делать))
Быстрее будет не пакетным запросом, а просто левым срединением к виртуальной таблице. Таблица ьез параметра, значит просто приклеит таблицу итогов, без всяких заморочек
Спасибо, хотя и не узнал нового, вопрос, в данном примере если заменить предварительную выборку элементов с помещением в ВТ на единый запрос с соединением первой таблицы , как изменилась бы скорость? Свой ответ знаю, интересен ответ других людей и Автора
Соединение с подзапросами, а также с виртуальными таблицами - одна из причин неоптимальной работы запросов: its.1c.ru/db/metod8dev#content:5842:hdoc:vtable_join
@@ironskills-1cсоздание виртуальной таблицы - дорогая операция. Классически задача решается через левое соединение. Все преимущество вирт.таблиц при указании фильтра превратится в тыкву при размере, скажем, 100к записей, а при 100к*100к будет совсем грустно, в то время как левому соединению будет это безразлично.
Где можно скачать консоль кода ironskills ?
Скоро выпустим ролик про инструменты программиста)
четко и понятно. спасибо!
где научиться анализировать запросы с профайлером SQL ?
Не на этом канале😂
В данном конкретном случае убрал бы цикл к чертям. Таблица.Загрузить(Запрос.Выполнить().Выгрузить()). И это кстати и приучает всё и всегда получать сразу в одном запросе.
Да, но при большом объеме данных метод Выгрузить() может привести к нехватке памяти, т.к. данные загружаются в оперативную память) Через выборку - более щадящий режим, хоть и кода больше писать надо)
Эммм только начал изучать, и у меня возник вопрос зачем цикл для заполнения табличной части, разве нет способа заполнить скажем так ТаблицаюЗаполнить(ВыборкаТовары), ну это как пример, думаю что долждны быть какието еще параметры. скажем сотриторва в табличной части по наименованию.
Напрашивалось использование "ЗаполнитьЗначенияСвойств" - при заполнении табчасти обработки
В этом как раз и преимущество подачи материала от Ивана -
Он не перегружает и не вываливает разом все свои знания на новичков.
Про ЗаполнитьЗначенияСвойств у него на курсе есть отдельный блок.
Где ссылка на эту обработку - консольку?
Иван, моё почтение! А о внешних компонентах когда замолвите слово? 😊
Немного позже, но сделаем)
Спасибо за ролик, некоторые полезные вещи подчерпнул. Только один вопрос. Зачем создавать вторую временную таблицу для выборки регистра? Почему нельзя сразу соединить Справочник.Товары с регистром остатков в одном запросе?
Чтобы проиндексировать поле Номенклатура. Тогда итоговый запрос будет выполняться в разы быстрее. Хотя можно поставить ее с левой стороны, а справа первую проиндексированную таблицу. Но это надо проверять. И желательно на больших объемах.
Потому что если виртуальная таблица собирает данные из нескольких физических таблиц, то на уровне SQL это реализуется как подзапрос к этим таблицам и в нашем запросе получается соединение с подзапросом, которое очень сильно зависит от разных условий(актуальности статистики, типа СУБД и т.д.) и может работать нестабильно, поэтому лучше выбрать данные регистра во временную таблицу и проиндексировать её.
Тогда еще такое: почерпнул без Д