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