Как стать автором
Обновить

Комментарии 32

Статья понравилась, но столько отсылок к 1с? ЕЕ крутить замучаешься чтобы она базу хотя бы приблизительно нормально использовала. И даже тогда, откройте мониторинг запросов и посмотрите что именно она делает. Я несколько раз в разных режимах проводил такие набеги, страшнее не видел ничего.

Просто 1с хороший пример как разработчики делая orm удобным для программиста 1с (а он реально удобен) совершенно не заботятся о производительности. Хотя у них и devops и хорошая обратная связь от франчайзи есть. А ведь им еще захватывать сданный без боя рынок финансовых систем западных вендоров. Да под капотом там "миниган" из dml . Если еще им воспользуется программист 1с который статьи о оптимальном программировании на языке 1с на its.1c.ru не читал , тут и оборудование не спасет

Он удобен? Мире Hibername/Doctrine - да, в мире 1с - на три (ну ок, на два) порядка хуже. А вообще проблема не в том что там "миниган" (хотя еслиб он стрелял только когда его просят это еще было бы переживаемо), а в том что там "тупой миниган".

Мой личный рекорд - отчет, который формировался 40 минут, уложить в запрос со временем выполнения 0.9 сек без изменения данных/реконфигурации базы/добавления индексов. Это совершенно за гранью добра и зла.

Про программистов я согласен, но у них даже в стандартных конфигурация полно дурдома и вычислений на стадии запроса.

Он удобен? Мире Hibername/Doctrine - да, в мире 1с - на три (ну ок, на два) порядка хуже.

Хуже чего?

А так да удобен - скажите где при создании экземпляра объекта (напр документ с собственными табличными частями и реквизитами) вы сразу получите готовый интерфейс, и отображение в СУБД с индексами ? И это без отладки и СМС. Причем эту конфигурацю Вы можете портировать на любую и 4х поддерживаемых СУБД просто импортом \ экспортом. Это реальный Rapid Application Development где можно реально быстро получить результат

Мы ворочаем у себя 5 терабайтной базой, при грамотном подходе к реализации причем только средствами 1С без прямых запросов к MS SQL . Принципы и приемы изложены тут Язык мой – враг мой / Хабр (habr.com) . Это возможно если рассматривать платформу как инструмент для генерации запросов, то подогнать запрос\инструкцию 1С под хороший план вполне можно. Это своего рода создание оптимального паттерна программирования

Типовые конфигурации 1С проектировались без оглядки на обработку больших объемов, хотя можно было бы делать по другому. Видимо политика "Лучше 10 маленьких клиентов чем один большой" еще действует. Но времена меняются когда читаешь это Фирма «1С» открывает новую компанию с бывшим менеджментом российского офиса SAP (infostart.ru)

Тупость "минигана" в 1С проявляется прежде всего на операциях записи поскольку там вариантов оптимизации почти нет. С обычными запросами к базе все проблемы решаемы хотя с общими разделителями они промахнулись Лучшее соединение враг хорошего? / Хабр (habr.com)

Кстати никто не запрещается создать свою внешнюю компоненту в 1С со своим отображением на СУБД - Api полностью открыт. Правда есть один нюанс, механизм отчетов тоже придется делать внутри компоненты

скажите где при создании экземпляра объекта (напр документ с собственными табличными частями и реквизитами) вы сразу получите готовый интерфейс, и отображение в СУБД с индексами

Doctrine/Hibernate как раз позволяют. Причем действительно с индексами и внешними ключами.

Тупость "минигана" в 1С проявляется прежде всего на операциях записи поскольку там вариантов оптимизации почти нет.

Как раз это не было бы проблемой, я серьезно, включите мониторинг запросов, посмотрите.

Кстати никто не запрещается создать свою внешнюю компоненту в 1С со своим отображением на СУБД - Api полностью открыт. Правда есть один нюанс, механизм отчетов тоже придется делать внутри компоненты

API у 1с ну очень своеобразное. Например операция удаления вообще не имеет контроля целостности, метки проведения/удаления можно поправить не исполняя проведение/удаление, а уж как весело для каждой конфигурации/объекта вычислять какие свойства ты можешь поправить а какие нет... Штука на самом деле неплохая на самом деле, но местами проще в базу залезть ей богу, или портировать данные вовне и там разобрать.

>

"Тупость "минигана" в 1С проявляется прежде всего на операциях записи поскольку там вариантов оптимизации почти нет.

>Как раз это не было бы проблемой, я серьезно, включите мониторинг запросов, >посмотрите.

Вы про какую типовую конфигурацию говорите? Просто операции чтения порождаются в трех случаях

а) Чтение объекта\набора записей перед обработкой типа Ссылка.ПолучитьОбъект() . В этом случае в память читаются как основная таблица так и связанные табличные части (документа, записи справочника и т.д.) . Здесь программист ничего поменять не может, да и проблем это не доставляет особых - всетаки 1C это объектная модель. Если меняешь объект его нужно менять c учетом ACID

б) Длинное обращение к реквизитам через точку Типа Ссылка.Контрагент.ОсновнойБанковскийСчет.Номер - тут 1С действительно сделает запрос на соединение из нескольких таблиц. Но программист может нормальный запрос на языке 1С написать, если в данном участке эффективность важнее , простоты кодирования . Есть соотвествующие статьи на ИТС Чтение отдельных реквизитов объекта из базы данных :: Обработка и модификация данных :: Система стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8 (1c.ru)

в) при использовании языка запроса 1С . Но тут все зависит от программиста, как напишешь так и отразится на SQL .

Я могу только две задачи озвучить где средствами языка запросов 1С невозможно эффективно решить проблему чтения, но это когда объем базы уже несколько терабайт.

В целом да повлияла 1803 против 1374 в предыдущем тесте, т.е. рост 31% процент. Т.е. меньше чем 1% на поток

непонятно, как вы этот 1% насчитали

31% / 50 фоновых заданий =0,62 % т.е. Меньше 1% на поток. Округлил для удобства восприятия

Как говорил кто-то: М - Математика!

Т.е. сначала 1803 / 50 -> 1374 / 50 -> ~ 31%. Не?

По поводу ОРМ, то она, помнится, не в языках программирования встроена, обычно, а в фреймворках. 1С тут - скорее исключение, как предметно-ориентированный язык. У всяковских там питонов, пых и прочих есть масса фреймворков, которые содержат массы реализаций ОРМ, на которые ты, при необходимости, можешь повлиять. В 1С так нельзя. Более того, там нельзя прямком в базу писать, ибо это нарушает лицензионное соглашение и может привести к отказу в обслуживании (ага, как будто они кого-то без этих нарушений "обслужат", ежели у них что накроется медным тазом). Ну писать - ладно, так и читать-то нельзя прямиком из базы.

Как говорил кто-то: М - Математика!

Т.е. сначала 1803 / 50 -> 1374 / 50 -> ~ 31%. Не?

1803 и 1374 записей в секунду, это суммарный показатель который дают 50 параллельных потоков (Скор1+Скор2...+Скор50)=ОбщаяСкорость

Процент прироста

ОбщийПрирост/(Скор1+Скор2...+Скор50)=ОбщийПрирост/ОбщаяСкорость=31%

Мы же смотрим какой % вкладывает один поток в общий прирост, поэтому 31 делим на 50

У всяковских там питонов, пых и прочих есть масса фреймворков, которые содержат массы реализаций ОРМ, на которые ты, при необходимости, можешь повлиять. В 1С так нельзя. 

За питон не скажу, но например в Java JPA базовые библиотеки ориентированы на работу либо с одной записью либо с набором но по одному ключу , что исключает обработку нескольких документов с разными номерами одним методом. Изменить это конечно можно написав собственный набор объектов даже базируясь на JPA , но по сути у Вас получится отдельный собственный ORM

Ну писать - ладно, так и читать-то нельзя прямиком из базы.

Дав программисту 1С ORM 1С тем самым позвляет ему владеть меньшим объемом знаний - логика понятна. Свобода работы с базой в "нормальных языках программировани" с ORM это иллюзия . ORM загоняет программиста в определенную версию стандарта SQL причем не самую новую . Просто попробуйте использовать чтото подобное table of records в SQL запросе для JPA

Мы же смотрим какой % вкладывает один поток в общий прирост, поэтому 31 делим на 50

то есть если машина удвоила скорость (+100%), то каждое из 4 колёс стало крутиться на 25% (100%/4) быстрее? )))

Если каждый поток обрабатывает в среднем 27 записей в секунду, а 50 потоков работают параллельно какая тогда общая скорость приложения из 50 потоков? Посчитайте и аналогия с колесами отпадет

один обрабатывает n запросов в секунду, 50 — 50⋅n.


если у нас появился новый поток n', который на 30% быстрее, то он обрабатывает
n'=n⋅1.3 запросов в секунду, а 50 таких потоков
50⋅n'=50⋅(n⋅1.3)=(50⋅n)⋅1.3
ровно на 30% больше, чем первый вариант.


аналогия с колёсами не отпадает )

Наверное долго формулой отвечать - просто на цифрах

1803-1374=429 записей \ сек это общий прирост на 50 потоков, на каждый поток приходится в среднем 8.58 записей \ сек прироста . 429 записей\сек прироста это 30% от общей скорости 1374 зап \сек. Как оценить вклад\долю одного потока (прирост 8.58 записей\сек) в общий прирост ? 8.58 / 1374 =0.62% . В своих выкладках за 100% я принимаю 1374 запись в сек общей скорости. Почему? Просто скорость фоновых заданий разная по техническим причинам получается

извините, но вы пишете бред.


обозначим:
v₁=1374, v₂=1803, v₂-v₁=429, единица измерения — запись/сек
N=50, единица измерения — поток


дальше вы считаете:
(v₂-v₁)/N
и делите на v₁
получается ((v₂-v₁)/N)/v₁=((v₂-v₁)/v₁)/N=((v₂/v₁)-1)/N


внутри скобок безразмерная величина, 30%, которую вы делите на число потоков, получается 0.006 поток⁻¹ (процент мы уже не можем использовать, проценты применимы только к безразмерным величинам). и что это может означать?

У вас плохая аналогия потому что скорость машины не является суммой скорости колёс.

Т.е. 1374 - это не 50 потоков, а 1803 - это 50?

Один поток в новом варианте = 1803/50 = 36,6, один поток в старом варианте = 1374 / 50 = 27,48 => 36,6 / 27,48 = 1,33 = +33%. ЧЯДНТ?

По поводу ОРМ, то разработчик на 1С ограничен ОРМ от 1С для записи данных в базу. Объясняется это тем, что нужно соблюдать ACID. Вне зависимости от того, на сколько этим ACID в данной конкретной ситуации можно пренебречь в угоду производительности. Но этим пренебрегают даже банки. А в 1С этого сделать нельзя вот никак вообще. В то время как во всех фреймворках, код которых в части ОРМ открыт, никто не мешает при необходимости эту ОРМ чуть-чуть подкрутить (шардирование, например, воткнуть).

Ну и полное отсутствие обновления данных через UPDATE в угоду все тому же ACID делает механизмы обновления крайне проблемными с точки зрения производительности. Напрмер, чтобы перепровести все документы (а это зачастую единственный путь получить "правильный" срез учета), необходимо их всех перезаписать с признаком проведения, в итоге в СУБД для каждого объекта запустится последовательная транзакция, в ходе которой сначала все данные объекта удалятся из базы, удалятся связанные с ним движения во всех регистрах, потом объект, даже если он не изменился, запишется в базу (даже если в нем сто таблиц по сто строк - они все были удалены), потом запустится код, который сформирует набор записей в регистрах накопления и сведений, после чего они будут записаны, потом будут записаны изменения в таблицах изменений объектов (по количеству планов обмена, требующих регистрации изменений). И все удивляются, почему это все так сильно тормозит. Ну а фиг ли...

Напрмер, чтобы перепровести все документы (а это зачастую единственный путь получить "правильный" срез учета)

???
срезы на любой момент 1с с помощью своих регистров отлично умеет делать как раз. массовое перепроведение обычно требуется для исправления накопившихся по каким-то причинам в регистрах данных.

???

Ну вот Вы в 1С оформили документ покупки барахла, которое хотите продать. Потом продали. А потом оказалось, что нужно бы транспортные расходы отразить, ну или оказалось, что количество не совсем то, или еще что-то. Вы документ поступления корректируете, добавляете затраты, но Вы уже продали барахло, т.е. оформили документ продажи, который списал партии по старой цене себестоимости. И если Вы документ поступления скорректируете, то списанная себестоимость документа продажи сама себя не скорректирует.

То же самое с оплатами, которые 1С автоматически раздербанивает по исторически сложившейся последовательности документов отгрузки/поступления, и если они вдруг были скорректированы, то у вас будет что-то недосписано. Т.е. образуется некая кредиторская/дебиторская задолженность в разрезе отдельных аналитических признаков учета (договор, документ, контрагент даже). И чтобы все стало красиво, 1С-неги не придумали ничего лучше (нет, придумали - РАУЗ, но это не помогает с "бабочками" по ДЗ/КЗ), чем перпровести документы. Вот такая вот интересная штука эта 1С. И для всего этого есть даже специальный механизм - последовательность учета. При том эти последовательности могут быть не в одном экземпляре, например, по ДЗ/КЗ и по партиям, по кадровым документами, по производственному учету и по всему тому, что еще было напихано в конкретное решение.

так это вам не срезы нужны, а требуется исправить цепочку ошибочных документов.
да, для общего случая решения лучше «отменить всё и создать документы заново» нет. не вижу тут никакой специфики 1с.

Т.е. 1374 - это не 50 потоков, а 1803 - это 50?

50 потоков в обеих тестах. Просто потоки работают параллельно и 1374 записей\сек или 1803 записей\сек это скорость посчитанная суммированием скоростей потоков. Поэтому когда Вы считаете среднюю скорость потока то по Вашей логике - если у каждого она увеличилась на 33% то общая увеличится 33%*50=1650% а в тесте не так. Лучше я Excel полный выложу.

По поводу ОРМ, то разработчик на 1С ограничен ОРМ от 1С для записи данных в базу. Объясняется это тем, что нужно соблюдать ACID

Ихмо это всего лишь одна из причин, там же еще guid кластеру нужно генерить и еще много чего

В то время как во всех фреймворках, код которых в части ОРМ открыт, никто не мешает при необходимости эту ОРМ чуть-чуть подкрутить (шардирование, например, воткнуть).

Как при шардировании сделать эффективный Join таблиц? Я думаю что не каждый программист может Map Reduce прикрутить. Мне кажется шардирование это уже другая лига

Ну и полное отсутствие обновления данных через UPDATE в угоду все тому же ACID делает механизмы обновления крайне проблемными с точки зрения производительности. Напрмер, чтобы перепровести все документы (а это зачастую единственный путь получить "правильный" срез учета), необходимо их всех перезаписать с признаком проведения, в итоге в СУБД для каждого объекта запустится последовательная транзакция

Вообще лучше бы MERGE тем более он входит в свежие стандарты SQL . Вообще как сделать эффективным запись в банальный регистр накопления с итогами, это очень интересная тема. С одной стороны использование средств специфичных для СУБД (tables of records, или forall из Oracle) 100% сделают код Orm закрытым, с другой стороны можно и стандартом SQL свежим обойтись если делать по одному DML на 1000 записей.

Кстати 1С догадывается что тотальный delete insert пагубен для производительности и как показано в Концепция ORM как двигатель прогресса — выдержит ли ее ваша СУБД? / Хабр (habr.com) контролирует измененность записи на сервере приложений. Т.е. распределение логики между сервером приложений и СУБД тоже хорошая тема для ORM но опять же при запси сущностей группой по 100-1000 записей

Т.е. распределение логики между сервером приложений и СУБД тоже хорошая тема для ORM но опять же при запси сущностей группой по 100-1000 записей

Основная проблема тут - это то, что при проведении документов (по крайней мере реализации) нужны "исторические данные", ведь таблицы проводок формируются программно. А для "исторических данных" нужны записанные таблицы остатков, которые могут быть прочитаны. Нам нужны партии, взаиморасчеты, остатки, резервы, ... И если писать пачками, то на что ваять селекты на эти самые остатки всего на свете? Тот же подход с контролем регистров накопления при записи в модуле их менеджера как бы намекает, что пачками вряд ли что получится - это ж не справочники обменами гонять между базами - там в этом был бы смысл, но клятый ACID...

.. И если писать пачками, то на что ваять селекты на эти самые остатки всего на свете?

Если конечно логику проведения документа закладывать в процедуру ОбработкаПроведения документа , да проблем такого рода не избежать поскольку уже единицей обработки является документ а не пакет документов. Такой подход оправдан если нужно автоматизировать отдел продаж где менеджеры обрабатывают заявки.

Но если у Вас Озон-Амазон или сделки по ценным бумагам в крупном брокере у Вас и архитектура приложения будет строится иначе

  • Интеграция с фронтом (поскольку на 1С фронт не напишешь хорошо хотябы по линцензионным причинам, только бэкофис)

  • Оперативное проведение (с упрощенным контролем\фиксацией остатков оперативного учета, но без проводок)

  • Перепроведение (как часть процедуры закрытия дня, недели)

И вот для задач перепроведния, работа с пакетами документов будет строится не из модуля документа (ОбработкаПроведения) а отдельной обработкой которая будет создавать проводки сразу для 1000 документов в памяти кластера и потом уже постить.

При этом ACID тут не мешает совершенно

  • Во первых все зависит от ключей по которым делятся сущности это может сделать обработка, и пакеты \ группы документов будут постится независимо

  • Во вторых процедура закрытия дня\недели может делатся в технологические окна роботами если не хочется усложнять архитектуру

Даже если у Вас алгоритм, который трудно параллелится напр FIFO его можно параллелить в разрезе (товаров\ценных бумаг и т.д.) , фиксировать остатки только на конец дня, а день считать в памяти.

Приемы крупным планом представлены тут

Язык мой – враг мой / Хабр (habr.com)

Главное не считать типовые конфигурации за правильный паттерн, это скорее всего антипаттерн с точки зрения маштабируемого решения. Даже 1С ЗУП на 5000 человек в типовом варианте это показывает, а там параллелить обработку легко. Нагруженный процесс к типовым конфигурацям лучше делать свой как отдельную подсистему, а учет муторных но небольших объемов оставить на механизмах типовой. Большая проблема кроется именно в регистрах с итогами, там прямо архитектурно место для deadlock

Если речь зашла о записи в лог, то для MSSQL важнейший параметр Delayed Durability

Думаю это просто еще один способ оттянуть неизбежное . В первой части ссылка на статью хабра есть. Но когда читаешь раздел data loss https://learn.microsoft.com/en-us/sql/relational-databases/logs/control-transaction-durability?view=sql-server-ver16#bkmk_DataLoss есть подозрение что это не для prod . Но как нибудь проверю и этот параметр

Для prod. Он не нарушает порядок записи в Wal. Почты теоретически вы можете потерять доли секунды работы

Мне только не понятно , Delayed Durability он может потерять завершенную транзакцию или незавершенную. Поскольку незавершенные и так откатываются в обычном режиме. Нет ли тут каких то подводных камней типа разрушеных условий primary key, нумерации Identity?

Разрушенных условий быть не может. А вот закомиченую транзакцию вы потерять можете (как и в асинхронном always on и при ресторан из бэкапа плюс транзакшн логи). Но как правило речь идёт о доляжх секунды.

Так что базы для импорта данных вы точно можете в этот решим перевести (и одинокие инсерты ускорятся в десятки раз), переводы денег между счетами в банке вероятно нет, но есть куча не такой критичной деятельности.

Точно также при асинхронном always on.

А он что-то делает помимо снижения частоты сброса буферов?
На dc ssd штраф на синхронную запись фактически нулевой, то на боевом сервере прироста производительности может и не быть (а вот на машине разработчика он может быть очень существенным).

И тем не менее. Вот скрипт ниже. Тестировал на SQL 2019, на локальном SSD. Workload - короткие транзакции. Машинка домашняя, старая. Попробуйте у себя - поделитесь,

133590 ms без Delayed durability (7489 inserts/sec)
33116 ms с Delayd Durability = FORCED. (30211 inserts/sec)

create table test (n int identity primary key, v varchar(128))
GO
set nocount on
declare @n int=1000000, @t datetime=getdate()
while @n>0 begin set @n = @n - 1 insert into test values ('*************') end
select datediff(ms,@t,getdate())
GO
drop table test

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории