Публикации ›
WMS на базе 1С:Предприятие 8 - покупка готового решения или самостоятельная разработка? ›
#113
19.12.14 19:18
ctpayc, вы хоть текст выше читали? В материале не разбираются конкретные системы, не отслеживается история применения тех или иных приемов, идет лишь анализ в целом проблематики построения высокоэффективных систем класса WMS на базе платформы 1С.
По поводу конкретных реализаций в 3-ей редакции и в 4-ей редакции можно отдельно обсудить, там есть над чем поспорить т.к. заложенные архитектурные решения имеют ряд серьезных недостатков. Например, использования в 4-ой редакции системы новые подходы имеют множество спорных решений.
КлючАналитикиУчетаНоменклатуры - новая сущность, которая будет размножаться вместе со справочником Номенклатуры, умножаясь на количество статусов для каждого товара, а также количество партий. Поиск по нескольким реквизитам в самом справочнике невозможен из-за ограничения платформы 1С. Для обхода этого ограничения был добавлен регистр сведений АналитикаУчетаНоменклатуры с реквизитами Номенклатура, Статус, Партия и ресурсом в виде ссылки на справочник. Использование регистра сведений позволит выполнять поиск сразу по нескольким значениям, но опять же имеем в нем то же количество строк, что и в справочнике.
Требуется проверка производительности выполнения запросов, где в качестве условия при получение данных из регистра ОстаткиТоваров указывается вхождения ключа аналитики в список элементов ключей, полученных из регистра АналитикаУчетаНоменклатуры. Дело в том, что основным ключом (primary key) таблицы справочника является длинный код, который создается уникальным на каждый элемент справочника. Когда мы пытаемся установить отбор по списку элементов с одной номенклатурой, но разными статусами или партиями, то для одного и того же товара будут существовать несколько элементов справочника, а значит они могут обладать разными основными ключами (IDRRef), т.е. нужные записи могут находится в разных частях таблицы т.к. таблицы упорядочены по этому ключу. Это как минимум приведет к чтению большого количества страниц таблицы и увеличение операций ввода/вывода, как максимум к невозможности использовать индекс для поиска элементов и использование перебора всей таблицы (Table scan или Index Scan). Если бы в таблице остатков напрямую находились реквизиты Номенклатура, Статус и Партия, то записи остатков одного товара всегда бы находились рядом т.к. основной ключ Номенклатуры (первого измерения в регистре остатков) был бы для всех строк неизменным.
Т.к. в регистре ОстаткиТоваров реквизит Контейнер является ссылкой на справочник Контейнеров, то для возможности хранения товаров в ячейках без контейнеров (без паллет, например в ячейках мелкоштучного отбора) потребовалось пойти на ухищрение - каждой ячейке создается связанный с ней Контейнер. Т.е. справочник Контейнеров содержит не только список паллет и коробок, которые являются перемещаемыми единицами, но и список ячеек склада для того, чтобы можно было отразить остаток товара в ячейке без паллеты при выбранном способе хранения остатков. При создании ячейка автоматически создается контейнер с тем же кодом, а также создается тип контейнера на основе типа ячейки. Для привязки контейнера и ячейки создается служебный документ ВводПоложенияФиксированногоКонтейнера, который создает запись в регистре ПоложениеКонтейнеров с ячейкой и контейнером. Т.е. мы получаем виртуальный контейнер в каждой ячейке равный по размеру самой ячейке.
Выбранная схема хранения остатков не дает получить данные одним запросом, а требует извлечения данных из разных таблиц, а главное из одной и той же таблицы с разными отборами. Для ускорения таких расчетов во всю используется пакетные запросы, где требуемые данные помещаются во временные таблицы, а потом используются повторно в следующих подзапросах и так далее, пока на последнем подзапросе не будут собраны все нужные данные в один выходной результат.
Такой подход при извлечении нужных данных требует не только лишнего времени на обработку каждого подзапроса, но и достаточного количества оперативной памяти для хранения временных таблиц для каждого пользователя. Плюс способы отбора на каждом шаге и соединения таблиц выбраны не самые оптимальные, что не позволяет использовать самый быстрый способ выборки данных - бинарного поиска по индексу (Index Seek).
Это касается не только хранения остатков, но и других алгоритмов. Например, в запросе планирования отбора используется пакет запросов из 14 подзапросов, каждый из которых может состоять из соединения нескольких таблиц и результат которого сохраняется во временной таблице.
Использования отдельных подзапросов также предполагает, что сам разработчик правильно организует выборку данных т.к. в таком варианте SQL сервер не может использоваться свою статистику для выбора того или иного алгоритма соединения нескольких таблиц и отбор из них данных.
И так далее, вопросов очень много к архитектуре решения...
Но это статья совсем не об этом!