Добрый день!
Давно известная проблема, когда большой(относительно, ну, скажем ~100 000 элементов) справочник с кучей индексируемых полей, и нужно добавить в него один или несколько реквизитов, 1С7.7(DBF) "умирает" на несколько(иногда свыше 10) часов...
Да, есть костыли по обходу этой проблемы, в частности можно добавлять поля через редактор DBF, у меня есть отработанная технология...
Но, иногда - лень...
Заметил, что штатно, в конфигураторе это выполняется в транзакциях по 1000.
Но, как-то крво все равно... До 10 000 элементов, все более-менее терпимо, а когда общий счетчик переваливает за 30 000, внутри транзакций начинаются тормоза на счетчике свыше 500...
Можно как-то пропатчить EXEшник или какие-то файлы ресурсов, что-бы уменьшить размер этих системных транзакций в два раза, с 1000 до, например 500?
Никто не заморачивался на эту тему?
Кариинка для пояснения... Начал вчера, уже жалею, что редактором не сделал, по "отработанной технологии", но прерывать уже не хочу - осталось не много, исходный размер DBF-ки ~54 Мб...
(https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-572.jpg)
Собрал стенд: пустая конфа, единственный справочник: Код Строка20, Наименование Строка100, Рекв1 Строка20, 200000 уникальных элементов, dbf 40 мегабайт.
Мне кажется, проблема не в самом пересчете индекса, а в том, что алгоритм перерасчета корявый (для каждого следующего элемента перестраивает и перезаписывает всё сначала? факториал как в «проблема с сохранением в Excel»?). И гипотетическое уменьшение размера транзакции проблему не решило бы. Подобное поведение хорошо видно при первоначальном заполнении. Например, если поставить для Рекв1 галки «Сортировка» и «Отбор по реквизиту» в пустой базе, а потом обработкой заполнять справочник, то к 1500 элементов уже идёт замедление, которое не лечится транзакциями. Если ставить транзакцию 1000, то вторая будет тормозить уже на 800, третья на 500 и дальше каждый шаг всё дольше и дольше. При этом ещё и размер CDХ улетает в небеса.
Ну и при добавлении индексируемого реквизита ситуация похожая: пересчет всё медленнее и дольше для каждой последующей порции элементов в транзакции, файл индексов растет невообразимо, но если после пересчета удалить CDХ и проиндексировать, то пересчет пройдет быстро и размер CDХ будет разумным.
Так что быстрый вариант без ручной корректировки таблиц у меня получился такой:
1.Добавляем реквизит в рабочей базе, галку «Сортировка» пока не ставим, сохраняем - перестройка таблиц идёт быстро.
2.Копируем md и dd в другую папку, подключаем, ставим галку «Сортировка», сохраняем.
3.Подменяем md и dd в рабочей базе, удаляем соответствующий CDХ, запускаем монопольно - переиндексация идёт быстро - CDX 220 мегабайт.
Мне кажется, так чуть проще чем через редактор DBF. Сам делал подобное только однажды - в моих базах не было особой необходимости.
А оптимальное решение: уменьшить наименование. Потому что при тех же условиях и наименовании Строка75 - проблемы нет вообще. По формуле hogika максимальная длина индекса 117 байт. Золотое правило: наименование чем меньше, тем лучше.
В Типовых не зря Наименование - Строка(50), не помню кто и где я встречал - но было описано почему 50, там не только с длной индекса, но и еще что-то интересное было, хотя может туплю...
Поигрался ещё, для полноты картины. У меня получилось так:
Подтверждаю, 117 символов - безопасный индекс. 118 - тормоза при записи и тем более пересчете. Посмотреть формируемые индексы можно в 1cv.dd
Расчет допустимых индексных полей такой:
Имеем 117 символов.
Если справочник неодноуровневый, то вычитаем 10 символов (PARENTID - 9, ISFOLDER - 1).
Вычитаем максимальное индексируемое поле (Реквизит с установленной галкой "Сортировка"):
Строка - длина строки;
Дата - 8 символов;
Число - длина числа + 1 символ (точность, разделители триад и неотрицательность значения не имеют);
Агрегатный объект определенного типа - 9 символов (УРБД значения не имеет);
Агрегатный объект неопределенного типа - 13 символов (УРБД значения не имеет).
Получаем максимально возможный непроблемный размер наименования.
Если не используются строковые индексируемые реквизиты больше 20 символов (а все остальные возможные индексируемые реквизиты этому условию удовлетворяют), то максимальные 87 символов для наименования - обеспечат отсутствие проблем пересчета индексов при добавлении новых реквизитов в справочник.
В противном случае - расчет выше покажет сколько можно себе позволить: Наименование+СтроковыйРеквизит<=107 (117 для одноуровневого)
Наименование может быть пустое, размер кода элемента (максимум 24 символа - не имеет значение тип и серия) для расчета не играет значения, при пустом наименовании в индекс попадает только сам индексируемый реквизит, так что он вполне безопасно может быть Строка(117).
Вроде всё.
Ну и побочный эффект от ковыряния с индексами - как оказалось, процедура ВыбратьЭлементыПоРеквизиту() таит в себе много чудес. Но это уже не по теме.
Про 117 - давно известно было ;-)
"Ну и побочный эффект от ковыряния с индексами - как оказалось, процедура ВыбратьЭлементыПоРеквизиту() таит в себе много чудес."
- а вот это - поподробнее, интересно же!
давно же известно - клюшки неисчерпаемы как атом!
Цитата: Злоп от 20 августа 2024, 00:38Про 117 - давно известно было ;-)
Да, конечно. Я писал выше, что первооткрыватель, насколько знаю, - Владимир Ходаков aka hogik.
Хотелось просто разобраться и показать из чего эти 117 символов можно набрать.
И, кстати, как всегда, что-нибудь да забудешь:
Если справочник подчиненённый, то вычитаем ещё 9 символов на id владельца (PARENTEXT).
Цитата: Злоп от 20 августа 2024, 00:40- а вот это - поподробнее, интересно же!
А вот тут надо подготовиться и как следует всё потестить. Я распишу попозже.
"Да, конечно. Я писал выше, что первооткрыватель, насколько знаю, - Владимир Ходаков aka hogik."
- мне помнится что это было еще раньше чем Вова писал об этом. Но тут со 100% утверждать не буду, возможно путаю/запамятовал
Цитата: Злоп от 20 августа 2024, 00:38Про 117 - давно известно было ;-)
ИНогда - забываешь. Особенно если не знал :))))
Цитата: Харлампий Дымба от 19 августа 2024, 01:48Поигрался ещё, для полноты картины.
Надо наверное пару процедур написать для чекинга, в опенконфе и в интерпрайзе.
у меня есть БД с 280000 товарами - надо поиграться.
Цитата: Харлампий Дымба от 19 августа 2024, 01:48Поигрался ещё, для полноты картины. У меня получилось так:
неа.
#===============================================================================
#==TABLE no 25 : Справочник Номенклатура
# Name |Descr |Type[A/S/U]|DBTableName|ReUsable
T=SC84 |Справочник Номенклатура |A |SC84 |1
#-----Fields-------
# Name |Descr |Type|Length|Precision
F=ID |ID object |C |9 |0
F=PARENTID |ID parent obj |C |9 |0
F=CODE |object code |C |11 |0
F=DESCR |object description |C |80 |0
F=ISFOLDER |Flag - Is Line - Fol|N |1 |0
F=ISMARK |Flag Object is Marke|C |1 |0
F=VERSTAMP |Version stamp |C |6 |0
F=SP85 |(P)Артикул |C |25 |0
F=SP86 |(P)БазоваяЕдиница |C |9 |0
F=SP208 |(P)Весовой |N |2 |0
F=SP2417 |(P)ВидНоменклатуры |C |9 |0
F=SP97 |(P)МинОстаток |N |15 |3
F=SP5066 |(P)НеВключатьВпрайс |N |2 |0
F=SP5013 |(P)НомерГТД |C |9 |0
F=SP94 |(P)ОсновнаяЕдиница |C |9 |0
F=SP4427 |(P)ОсновноеСвойство |C |9 |0
F=SP103 |(P)СтавкаНДС |C |9 |0
F=SP104 |(P)СтавкаНП |C |9 |0
F=SP5012 |(P)СтранаПроисхожден|C |9 |0
F=SP8768 |(P)Цвет |C |50 |0
F=SP8769 |(P)Размер |C |10 |0
F=SP8770 |(P)Типоразмер |C |15 |0
F=SP8871 |(P)КодБазыПереноса |C |12 |0
F=SP8873 |(P)Префикс |C |1 |0
F=SP8874 |(P)ТорговаяМарка |C |9 |0
F=SP9154 |(P)аисТипМаркировкиГ|N |5 |0
F=SP10061 |(P)ТНВЭД |C |9 |0
#----Indexes------
# Name |Descr |Unique|Indexed fields |DBName
I=IDD |of ID |0 |ID |IDD
I=PCODE |of PARENT and |0 |PARENTID,ISFOLDER,CODE(UPPER) |PCODE
I=PDESCR |of PARENT and |0 |PARENTID,ISFOLDER,DESCR(UPPER) |PDESCR
I=CODE |of CODE |0 |CODE(UPPER) |CODE
I=DESCR |of DESCR |0 |DESCR(UPPER) |DESCR
I=VI85 |VI85 |0 |SP85(UPPER=128) |VI85
I=VIP85 |VIP85 |0 |PARENTID,ISFOLDER,SP85(UPPER=128) |VIP85
I=VI5066 |VI5066 |0 |SP5066,DESCR(UPPER) |VI5066
I=VIP5066 |VIP5066 |0 |PARENTID,ISFOLDER,SP5066,DESCR(UPPER) |VIP5066
I=VI8769 |VI8769 |0 |SP8769(UPPER=128) |VI8769
I=VIP8769 |VIP8769 |0 |PARENTID,ISFOLDER,SP8769(UPPER=128) |VIP8769
I=VI8871 |VI8871 |0 |SP8871(UPPER=128),DESCR(UPPER) |VI8871
I=VIP8871 |VIP8871 |0 |PARENTID,ISFOLDER,SP8871(UPPER=128),DESCR(UPPER) |VIP8871
117-25-10 = 82
DESCR - |object description |C |80 |0
и все равно тормоза (при пересчете) наблюдаются
Цитата: Харлампий Дымба от 17 августа 2024, 20:531.Добавляем реквизит в рабочей базе, галку «Сортировка» пока не ставим, сохраняем - перестройка таблиц идёт быстро.
Такой метод рабочий, но...
Добавляемый реквизит и так не индексируемый, проблема в том, что там куча других реквизитов с признаком "Сортировка" еще до меня было... 5 шук, один мой, добавил, потому, что уже терять нечего было - уже 4 до меня были добавлены. Тормоза идут из-за них. Получается, их нужно сначала отключить, потом опять включить... Проще получается редактором реквизит добавить. А наименование там и так 50 символов.
Цитата: Харлампий Дымба от 17 августа 2024, 20:53Если ставить транзакцию 1000, то вторая будет тормозить уже на 800, третья на 500 и дальше каждый шаг всё дольше и дольше. При этом ещё и размер CDХ улетает в небеса.
А с этим, похоже все так и есть... Нет смысла уменьшать размер транзакций, даже если такое можно как-то сделать :-(
Попробовал на тестовой базе, правда она ни о чем, всего ~15000 товаров.
Снял сортировку со всех реквизитов - думал долго будет эту операцию делать, но нет, быстро.
Далее все так как в #2...
Да, в принципе можно и так, возможно, даже быстрее, чем редактором.
Надо будет на большой базе попробовать.
Цитата: MWW_Ruza от 20 августа 2024, 19:04Снял сортировку со всех реквизитов - думал долго будет эту операцию делать, но нет, быстро.
Не... На реально больших базах - так-же "умирает" на 25000+... При снятии сортировки.
Так, что - пока редактором быстрее получается.
Цитата: MWW_Ruza от 20 августа 2024, 20:27Не... На реально больших базах - так-же "умирает" на 25000+... При снятии сортировки.
Хм. Ну ладно. Если максимальный из индексов проблемный (или был проблемный, а мы уменьшаем до непроблемного - снятие сортировки, например), то расчет по-пустому и расчет по-рассчитанному выполняется в любом случае достаточно долго. Но расчет по-пустому при этом значительно быстрее расчета по-рассчитанному.
Если все индексы непроблемные, то переиндексация достаточно быстрая.
Ну, не буду отстаивать своё, всё-таки рабочая база и тестовая база - есть разница.
Цитата: trdm от 20 августа 2024, 16:39и все равно тормоза (при пересчете) наблюдаются
Может это просто тормоза? Ну типа ужас, но не ужас-ужас!
Вот если на двух копиях КодБазыПереноса сделать Строка(20) и Строка(30) - разница во времени перерасчета будет огромная, я думаю. Но это если есть время и желание.
Поковырялся ещё и понял, что ещё не учел:
Наименование не попадает в индекс к сортируемым реквизитам, если установлена только галка "Сортировка" (нужна для ВыбратьЭлементыПоРеквизиту() и .НайтиПоРеквизиту() и для сортировки в списке справочника). То есть в этом случае длину наименование можно не добавлять к длине реквизита.
Наименование попадёт в индекс к сортируемым реквизитам, только если установлена галка "Отбор по реквизиту" (нужна для .УстановитьОтбор() и для отбора в списке справочника).
Ну и есть ещё местами противоречивая информация с ИТС:
Например, для регистра указано, что ключ - максимум 120 символов и упомянуто, что из них 8 символов зарезервировано в служебных целях (может и для справочников так же?). А при построении индексного ключа в запросе указано, что дата - 10 символов, а всё остальное +1 символ от того, что я указал выше.
В общем, хотел какую-то ясность внести, но - не получилось.
Цитата: MWW_Ruza от 20 августа 2024, 18:38Цитата: Харлампий Дымба от 17 августа 2024, 20:531.Добавляем реквизит в рабочей базе, галку «Сортировка» пока не ставим, сохраняем - перестройка таблиц идёт быстро.
Такой метод рабочий, но...
Добавляемый реквизит и так не индексируемый, проблема в том, что там куча других реквизитов с признаком "Сортировка" еще до меня было... 5 шук, один мой, добавил, потому, что уже терять нечего было - уже 4 до меня были добавлены. Тормоза идут из-за них. Получается, их нужно сначала отключить, потом опять включить... Проще получается редактором реквизит добавить. А наименование там и так 50 символов.
Если так, то мне помогало удаление нужного cdх перед сохранением (реструктуризацией), а другое ничего не надо делать (отключать/включать).