Организация кэширования данных для отчетов в 1С 8.2 #746647


#0 by ixilimuse
Доброго времени суток, коллеги! Может у кого-то из Вас родится идея в каком направлении стоит копать? У меня уже как говориться притупилось чувство объективности. Ищу свежих идей и взглядов. Суть примерно такая. Существует пяток отчетов основанных на одном "запросе ядре", но финальная обработка и количество полей и т.п. - у них разные. Сейчас это пять раздельных отчетов. (плюс есть ещё 8 аналогичных отчетов на другом "ядре запросе"). Так вот "Ядро запрос" выполняется от 8 до 16 минут. Результирующая временная таблица в максимальной вариации выдает 550 000 записей. При этом в таблице 68 полей. В целом всех все устраивает. Но мне надоело при каждой доработки "ядра запроса" не забывать доработать все запросы где это "ядро" используется. Решил я как-то взять и создать регистр сведений. Что бы вот эти основные подготовленные данные один раз получить и записать туда. А затем в отчете уже использовать регистр сведений для обработки этой большой таблицы и выбора нужных в нужном разрезе данные. Вариант 1. В регистре не периодическом 2 поля. Дата - На которую формируется отчет. ХранилищеЗначений - туда помещаю ТабЗнач. Не успел я придумать как буду извлекать от туда данные как 1С легла при попытке записать туда таблицу значений. В этом варианте не стал пытаться бить по партиям данные. К слову ради интереса записал в файл ТабЗнач и узрел что файл весит почти 1 Гб. Вариант 2. Создал регистр опять же не периодический, не подчиненный. И давай создавать 68 ресурсов для каждого поля запроса. Указывать для каждого поля конкретный тип ссылки поленился, и ставил "Любая ссылка" там где должны хранится ссылки.   В общем всю таблицу разом обломился записать. Добавил в рег.свед. поле "Партия". И в цикле из запроса выбирал по 2000 записей и так по 2000 записей хреначил в регистр 550 тыс записей. В целом запись - работает. Все как бы не дурно. Хотя 40 минут эта процедура занимает. Но проблема началась при извлечении данных из регистра. При получении хитрых срезов данных по определенным условиям и группировкам - 1С уходила в медитацию на неопределенное время. Больше 30-40 минут не ждал убивал сессию и баста. Есть мысль что проблема в типе "Любая ссылка". Нооо, на 100% не уверен что все таки в этом дело. Точнее не уверен что если сделать по нужному типу хранение - скорости значительно прибавятся. Вариант 3. Вообще взял да написал функцию для получения ТЗ. Думал буду один раз ТЗ получать и потом её передавать в запрос в качестве параметра, и таким образом одним "пакетом" выгружать сразу 5 отчетов всего один раз выполним большой и тяжелый запрос к базе. Но тут 1С опять начала плеваться эксепшенами о нехватки памяти, давать ссылки на какие-то модули *.cpp и т.п. В общем пока думаю все таки испытать вариант 2 но типы значений все ж таки в регистре привести к виду. Но если у кого-то возникнет желание раскритиковать мои методы и подкинуть свежих взглядов на задачу - буду очень признателен :)
#1 by Рэйв
Вариант 4. Напиши нормальный запрос для каждого варианта отчета и не гонись за "универсальностью".
#2 by ixilimuse
Тоже конечно вариант, но пока лежит на дальней полке ибо в конечном счете все равно тоже самое и напишу. На самом деле разница не значительная между отчетами. Друг на друге основаны просто отображение разное. Сложный запрос ввиду очень завороченной логике страховых бизнес процессов) 1,5 года 3 департамента добивались консенсуса меж собой. Как это должно выглядеть) Но опуская лирику я учту Вашу рекомендацию. Спасибо! :)
#3 by ixilimuse
Разница меж отчетами только в том что Нац.Банк желает видеть данные в таком разрезе, актуарии в таком, а статистика в другом. Кому-то всю простыню выворачивать надо, кому-то схлопывать. Ну и плюс минус 3-4 поля разнятся кому-то надо, кому-то не надо. А в остальном данные одни и те же во всех отчетах. Потому и хочу как-то их закэшировать.
#4 by dervishsy
Может попробовать sqlite в качестве места для хранения кэша. преимущество в том что базу sqlite можно убить и сделать заново при необходимости.Правда мало инфы по ее использованию. вот например .
#5 by Лефмихалыч
стену буков не читал. Ответ в агрегатах, денормализации и прочих OLAP-кубах
#6 by ixilimuse
Спасибо, надо будет покумекать. По сути можно и родной SQL где сама база 1С лежит заюзать. Но пока просто не вижу оптимального решения как это в данном случае сделать. И как это упростит работу. вот слово денормализации прям бурление мыслей спровоцировало. Благодарю.
#7 by mistеr
>мне надоело при каждой доработки "ядра запроса" не забывать доработать все запросы где это "ядро" используется. Не понял, как кэширование поможет решить эту проблему. Если структура результата "ядра" меняется, то менять нужно везде, по-любому. А если меняется не структура, а потроха (оптимизации и т.п.) то менять только в одном месте. У тебя ведь, надеюсь, запрос-ядро вынесен в функцию?
#8 by ixilimuse
Нет, в том и дело, что "ядро" в функцию не вынесено. В том и проблема что во первых каждый раз выполняя ядро мы тратим процессорное время. Во вторых мне как программисту оптимизировав к примеру один отчет приходится это проделывать с остальными. Все обстоит именно так ввиду того, что изначально делался один отчет. А потом внезапно в срочном порядке понадобились ещё и ещё отчеты. В итоге времени на переделку всего скопа никто не выделял. А с ростом количества отчетов их сопровождение требовало все больше времени. А сложность ещё в том что часть отчетов работает на СКД, а часть реализована "дедовским" методом.   В общем наконец мне удалось официально выделить под эту задачу рабочее время. Собственно пытаюсь теперь все разложить по полочкам.
#9 by ИС-2
а, если выгружать пачками, но не по строкам, а по колонкам. Т.е выгружаем колонку, помещаем ее в хранилище, записываем в регистр. Измерение регистра - номерколонки
#10 by RomanYS
МенеджерВременныхТаблиц?
#11 by ИС-2
у автора проблема - куда сохранить этот менеджер, чтобы использовать в другом месте
#12 by Fragster
типвсессылки + RLS = смерть
#13 by Fragster
хранить в РС - норм. можно еще в ВИД писать
#14 by Остап Сулейманович
В 1С есть обалденное хранилище всяких такого рода кешей. Хочешь - РегистрСведений, хочешь - РегистрОстатков.
#15 by Fragster
про денормализацию что-нибудь слышал?
#16 by Fragster
кстати, в той же УТ видно по количеству всяких вариаций ТоварыНаСкладах
#17 by Остап Сулейманович
Так это же оно и есть. Хранить в базе избыточную информацию для быстрого еЯ получения.
#18 by Славен
Загнать текст запроса ядра в общий макет и не рожать ежиков
#19 by Славен
+ Насколько я понял тебе не результат же запроса в кэше надо хранить, а текст ядра запроса в одном месте. Обычно такое загоняется в макет, а каждый отчет, который использует это ядро будет тянуть текст из макета. Если надо что то поменять, то меняется в одном месте
#20 by Остап Сулейманович
Обычно для таких целей пользуют либо общий модуль, либо модуль обработки (как в эпоху до исторического материализма), либо внешние обработки типа обработки заполнения. Использовать макет конечно можно... Но это напоминает нетрадиционные способы удаления гланд.
#21 by ixilimuse
Большое всем спасибо за встряску :) Уже как раз думаю над этим вопросом) В сторону денормализации. плюс хочу таки избавиться от типов ВсеСсылки и таки испытать что из этого выйдет. С учетом других штуковин) Тоже интересная концепция. Но затрудняюсь с тем как потом по шустрому извлекать эти столбцы) Все таки хотелось бы именно данные хранить. Так как даже если будет запрос в одном месте - не решится этим проблема долгого выполнения отчетов. Либо один раз за 15 минут получить нужный скоп данных и раскидать его по разным отчетам, или каждый отчет получает этот скоп индивидуально для себя. В итоге каждая декада отнимает приблизительно 2-2,5 часа на получение полного списка выгружаемых отчетов. (с учетом нагрузки на базу, блокировок и т.п.) Оно терпимо и все к этому привыкли, но осознание что можно было бы и быстрее не дает мне спокойно спать по ночам)
#22 by ixilimuse
+ В общем уже несколько идей связанных с денормализацией пошли в ход. Затем предыдущие приводимые мной варианты попробую немного облегчить и попытаюсь таки запустить. Если у кого-то будут ещё предложения по прежнему буду рад выслушать. Ну а если из моего "коллайдера" выстрелит птичка хорошего прироста скорости - отпишусь о подробностях) И ещё раз всем большое спасибо за участие в мозговом штурме)
#23 by ИС-2
хм, а если использовать модуль повторного использования для хранения данных
#24 by ИС-2
так может проще сформировать за 1 заход все 10 отчетов
#25 by ixilimuse
В принципе - тоже думал о таком. Есть в этом некоторое зерно рациональности. Но бывают ситуации когда по 1-2м договорам находят косяк. Исправляют их в базе. И вот тут я опасаюсь что такой модуль проявит себя не с лучшей стороны. Хотя надо будет проверить тоже. Да, я уже все свои отчеты оснастил экспортными методами. И в одной из обработок касаемых данной базы договоров дал возможность отмечать галками нужные отчеты и выгружать их в указанную директорию. Осталось только научить отчеты использовать один раз полученный свод данных для финального формирования специфических форм)
#26 by ixilimuse
То есть сейчас это как работает. В запросе формируется некая временная таблица. Которая имеет общий вид. Дальше в этом же запросе происходит отсекание в зависимости от специфики отчета не нужных данных и в итоге из запроса выгружается готовый обработанный отчет. Остается только в ТабДок выгрузить. И когда все это происходит на уровне СУБД, то бишь в запросе - оно работает нормально. Но запрос выполняется само собой не быстро. А вот как только я пытаюсь эту временную таблицу загрузить в память 1Ски для раздачи его нескольким отчетам тут и проявляются сложности с нехваткой доступных для 1С ресурсов. С чего собственно тема и родилась) Но некоторая денормализация в совокупи опять же с попыткой хотя бы часть данных закэшировать - дают надежду на удачное решение проблемы.
#27 by H A D G E H O G s
Многократноиспользуемый запрос, выполняющийся дольше 10 секунд, не имеет права на жизнь.
#28 by RomanYS
Если этот кэш не надо передавать между сеансами, то нужно использовать МенеджерВременныхТаблиц, его можно передавать из отчета в отчет. Если надо для всех или сохранять между сеансами, то конечно не прокатит.
#29 by mistеr
> Если у кого-то будут ещё предложения К сожалению, платформа не предоставляет (пока?) эффективных средств для массового DML. Поэтому как ни оптимизируй, а запись промежуточных данных в регистр останется узким местом. Ну, будет не 40 минут, а 20 или 15. А с учетом того, что в отчетный период "находят косяки и исправляют в базе", это придется делать многократно, и очень вероятно, что общая картина принципиально не поменяется. Есть вариант сосредоточиться на оптимизации получения данных. Это можно сделать с помошью агрегатов (если структура исходных данных вменяемая). Далее, по твоим словам, разные отчеты требуют разной детализации. Тогда есть смысл вообще отказаться от промежуточного хранения и написать для каждого отчета свой оптимальный запрос. Тогда эффект от агрегатов станет еще более ощутимым. При этом какие-то общие части все равно можно выносить в процедуры/функции, передавая данные через временные таблицы. В отличие от ТЗ, они не гоняются с сервера на клиент и обратно и не замедляют получение результата.
#30 by rsv
Напишите вьюху-ядро на T-sql .  Далее ее вызывать и отсекать условиями  в других N отчетах вьюхах....
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С