Имя: Пароль:
1C
1C 7.7
v7: 1SBLOB.dbf незаметно подкрался к 2 Гб
0 victuan1
 
21.04.20
20:35
Есть какой готовый внешний отчет, который бы проанализировал бы справочники и документы и вывел бы долю вклада каждого объекта метаданных в рост строк неограниченной длины?

Базу обрезали недавно, но она всё равно быстро выросла.
Пока грешу на служебные справочники Контуровского обмена EDI, встроенного в конфигурацию.
Проверил объекты Обмена с Меркурием - они не сильно "вложились" в рост строк неограниченной длины (я постарался по максимуму ограничить применение неогр. строк).
Но вот контуровская поделка в этом плане мне совсем не нравится.
Упаковку базы и проверку физ.целостности через ТИИ тоже делал - вообще никак не изменило объем базы.
1 victuan1
 
21.04.20
20:38
Пока запустил на ночь вот эту поделку http://1clancer.ru/catalog/1595 - вроде находит какие-то лишние записи. Посмотрю утром результат.
2 victuan1
 
21.04.20
20:41
За полтора часа обработала миллион записей из 20 млн - есть мнение, что до утра не выполнится ;)
3 Курцвейл
 
21.04.20
20:55
(0) Напиши сам запрос. Увидишь какие объекты и их реквизиты дали наибольший вклад в размер.
Точно не помню, но неограниченная длина автоматом резервирует какой объем. Получается что неограниченная длина строки с " " реально занимает больше информации, чем 1 символ.
4 Курцвейл
 
21.04.20
20:58
Еще есть вариант - выгрузить/загрузить БД. Это операции оптимизирует таблицы dbf и удалит пустые записи в 1SBLOB
5 Фрэнки
 
21.04.20
23:10
но там же 2 ГБ всего - если на одну запись приходится 1024 байта, то общее число будет 2 млн всего. Что-то там о 20 млн, т.е. по 100 байт в среднем на каждую запись?
6 vde69
 
21.04.20
23:19
20 лямов в записи ОДНОЙ таблице и Вы работаете с файловой 7.7 ? извращенцы... я уж молчу про переход на 8.3, но могли-бы хотя бы на SQL переползти...
7 Злопчинский
 
21.04.20
23:57
В блобе стрка неограниченная хранится блоками фиксированной длины, то ли по 80 то ли по 60 байт.
8 Гость из Мариуполя
 
гуру
22.04.20
00:45
по 80
9 victuan1
 
22.04.20
02:57
(3) Это всё понятно. Ищется готовый отчет, чтобы время сэкономить.
(6) Но восьмерка же еще сырая, как на нее переходить? ;) Второй по размеру файл дбф - всего 400 МБ. Надо с блобом разобраться, а не сломя голову на SQL переходить.
(2) За ночь обработалось 8 млни из 20 - прервал. Попробую на копии выгрузку/загрузку базы. Параллельно голову ломаю над контуровским справочником КонтурEDI_Сообщения - не нравится мне его структура с кучей строк неогр. длины.
10 victuan1
 
22.04.20
04:42
Интересно, если не удастся существенно уменьшить БЛОБ, то поможет ли "вирт" Через раз отображаются данные и некорректно выполняются обработки ?
11 Провинциальный 1сник
 
22.04.20
07:53
Переходите на sql-версию, там такого ограничения нет.
PS Что-то мне помнится, в начале двухтысячных было какое-то решение, которое эмулировало dbf для 1с через другую СУБД, при этом отсутствовали ограничения индексов в 2 Гб.
12 Djelf
 
22.04.20
08:57
(9) Тю. КонтурЕДИ... они же все сообщения в длинные строки засовывают и никогда не удаляют. Грохни там все,  кроме последнего месяца, все и исправится.
13 Злопчинский
 
22.04.20
09:01
(12) надо просто обработку для 1SBLOB наваять, которая возьмет id записей и распихает их в таблицу по типам и видам обьектов с подсчетом количества Кб по каждому типу-виду + по какому реквизиту...
как из 9-ти символьного ида получить тип и вид объекта?
14 ДенисЧ
 
22.04.20
09:06
(13) Из 9исимвольного никак. Но в блобе должен быть ещё один ид, типа.
Под рукой нет, не помню.
15 mishaPH
 
модератор
22.04.20
09:09
за запихивание чего либо в длинные строки бить палками нежадно
16 Злопчинский
 
22.04.20
09:09
(14) если из 9-ти симольного никак, то как 1Сина знает - куда подтягивать?
#===============================================================================
#==TABLE no 7      : Длинные строки
# Name    |Descr                         |Type[A/S/U]|DBTableName|ReUsable  
T=1SBLOB  |Длинные строки                |A          |1SBLOB     |1        
#-----Fields-------
# Name      |Descr               |Type|Length|Precision
F=FIELDID   |Field Id            |C   |4     |0        
F=OBJID     |Obj Id              |C   |9     |0        
F=BLOCKNO   |Block Number        |N   |4     |0        
F=BLOCK     |Block               |C   |80    |0        
#----Indexes------
# Name     |Descr         |Unique|Indexed fields                                              |DBName    
I=MAIN     |              |0     |FIELDID,OBJID,BLOCKNO                                       |MAIN
17 Djelf
 
22.04.20
09:14
(13) Нет, просто грохнуть и все. У них есть в каталоге КонтурEDI_ФормаСервис_УдалениеСообщений.ert
18 ДенисЧ
 
22.04.20
09:15
(16) По метаданным?
19 Злопчинский
 
22.04.20
09:24
(18) ну так как по метаданным?
открывается прогой документ. с полем "Комментарий" - как подтягиваются записи из блоба? OBJID - 9 символов - по нему система понимает какая запись в файле относится к этому документу? OBJID - уникальный в пределах всей базы?
20 vde69
 
22.04.20
10:33
ddl Ромикса подключали? на память уже непомню, она вроде до 3х(или до 4х) гигов позволяет файлы юзать
21 MarySue
 
22.04.20
10:44
(9)  а зачем вы храните сообщения в длинных строках справочника?  
Для файловой базы это моветон!
В модуле Контур.EDI давно уже есть возможность держать их во внешнем хранилище (в базе SQLite).
https://ibb.co/DQzpjKN
22 MarySue
 
22.04.20
10:57
Ну и да,  прав (12).
Нужно удалить старые сообщения сервисной обработкой КонтурEDI_ФормаСервис_УдалениеСообщений.ert (оставить только текущий год).
И затем сделать упаковку таблиц через конфигуратор.
23 Djelf
 
22.04.20
13:36
(0) Не было такого отчета. Теперь есть. Требует 1с++ и 1sqlite.
https://gyazo.com/47dad00bfe9b8e8e5ec8bff7c195ddb4


Процедура Сформировать()

    тз=СоздатьОбъект("ТаблицаЗначений");
    тз.НоваяКолонка("Ид","Число");
    тз.НоваяКолонка("Представление","Строка");
    
    мдв=СоздатьОбъект("MetaDataWork");
    Для НомерСправочника=1 По Метаданные.Справочник() Цикл
        Справочник = Метаданные.Справочник(НомерСправочника);
        Для НомерРеквизита=1 По Справочник.Реквизит() Цикл
            Реквизит = Справочник.Реквизит(НомерРеквизита);
            Если (Реквизит.Тип="Строка")И(Реквизит.Длина=0) Тогда
                тз.НоваяСтрока();
                тз.Ид = мдв.ИДОбъекта(Реквизит);
                тз.Представление = "Справочник."+Справочник.Идентификатор+"."+Реквизит.Идентификатор;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    Для НомерДокумента=1 По Метаданные.Документ() Цикл
        Документ = Метаданные.Документ(НомерДокумента);
        Для НомерРеквизита=1 По Документ.РеквизитШапки() Цикл
            Реквизит = Документ.РеквизитШапки(НомерРеквизита);
            Если (Реквизит.Тип="Строка")И(Реквизит.Длина=0) Тогда
                тз.НоваяСтрока();
                тз.Ид = мдв.ИДОбъекта(Реквизит);
                тз.Представление = "Документ."+Документ.Идентификатор+"."+Реквизит.Идентификатор;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    Для НомерРеквизита=1 По Метаданные.ОбщийРеквизитДокумента() Цикл
        Реквизит = Метаданные.ОбщийРеквизитДокумента(НомерРеквизита);
        Если (Реквизит.Тип="Строка")И(Реквизит.Длина=0) Тогда
            тз.НоваяСтрока();
            тз.Ид = мдв.ИДОбъекта(Реквизит);
            тз.Представление = "ОбщийРеквизитДокумента."+Реквизит.Идентификатор;
        КонецЕсли;
    КонецЦикла;

    База=СоздатьОбъект("SQLiteBase");
    База.Открыть(":memory:");
    База.УложитьТЗ(тз,"vt");

    Запрос= База.НовыйЗапрос();
    тз=Запрос.ВыполнитьЗапрос("
    |SELECT
    |Представление
    |,count [КоличествоБлоков]
    |,count*97 [ОбъемБайт]
    |FROM
    |(SELECT count(*) count,fieldid FROM __1S_BLOB GROUP BY FIELDID) as blob
    |JOIN vt ON blob.fieldid=id2str(vt.Ид,4)
    |ORDER BY count DESC
    |");

    глПросмотрТСЗ(тз);

КонецПроцедуры
24 Cthulhu
 
22.04.20
14:46
// (16): ня.
Функция ПолучитьОбъектПоИлВнутреннегоПредставления( Знач ИлВнутреннегоПредставления , Знач тБазаОЛЕ="") Экспорт
    Перем _Объект;
    Если СтрДлина(ИлВнутреннегоПредставления)=24 Тогда
        Если Лев(ИлВнутреннегоПредставления,1)="T" Тогда    // Счет - составляется по-другому
            _Объект="{""T"",""0"",""0"",""0"",""0"",""0"","""+Сред(ИлВнутреннегоПредставления,2)+"""}";
        Иначе//Если Лев(ИлВнутреннегоПредставления,1)<>"T" Тогда
            _Объект="{"""+Лев(ИлВнутреннегоПредставления,1)+""",""0"",""0"","""
            +Сред(ИлВнутреннегоПредставления,2,10)+""",""0"",""0"","""
            +Сред(ИлВнутреннегоПредставления,12)+"""}";
        КонецЕсли;
        Если ТипЗначенияСтр(тБазаОЛЕ)="OLE" Тогда
            _Объект=тБазаОЛЕ.EvalExpr("ЗначениеИзСтрокиВнутр("""+СтрЗаменить(_Объект,"""","""""")+""")");
        Иначе//Если ТипЗначенияСтр(тБазаОЛЕ)<>"OLE" Тогда
            _Объект=ЗначениеИзСтрокиВнутр(_Объект);
        КонецЕсли;
    КонецЕсли;
    Возврат(_Объект);
КонецФункции //ПолучитьОбъектПоИлВнутреннегоПредставления
Функция ПолучитьОбъектПоИдБазыДанных9( Знач ИдБазыДанных9 , Знач тБазаОЛЕ="") Экспорт
    Возврат(ПолучитьОбъектПоИлВнутреннегоПредставления(
    Лев(ИдБазыДанных9,1)+Формат(СокрЛП(_StrToId(Сред(ИдБазыДанных9,2,6))),"Ч10.0")
    +Формат(СокрЛП(_StrToId(Сред(ИдБазыДанных9,8,6))),"Ч10.0")+Прав(ИдБазыДанных9,3),тБазаОЛЕ));
КонецФункции //ПолучитьОбъектПоИдБазыДанных9
25 victuan1
 
22.04.20
15:23
СписокFIELDIDДляОбработки=СоздатьОбъект("СписокЗначений");
    
    ТаблицаФайлДИД=СоздатьОбъект("ТаблицаЗначений");
    ТаблицаФайлДИД.НоваяКолонка("IDFIND");
    ТаблицаФайлДИД.НоваяКолонка("FIELDID");
    ТаблицаФайлДИД.НоваяКолонка("OBJID");
    ТаблицаФайлДИД.НоваяКолонка("Содержание");
    ИмяДокумента="";
    ИмяРеквезита="";
    
    Попытка
        глМД = СоздатьОбъект("MetaDataWork");
    Исключение
        Если ЗагрузитьВнешнююКомпоненту("1cpp.dll")=1 Тогда            
            глМД = СоздатьОбъект("MetaDataWork");
        КонецЕсли;
    КонецПопытки;
    
    Для к  = 1 По Метаданные.Справочник() Цикл        
        Для сч = 1 По Метаданные.Справочник(к).Реквизит() Цикл            
            Если (Метаданные.Справочник(к).Реквизит(сч).Тип = "Строка")
                И (Метаданные.Справочник(к).Реквизит(сч).Длина = 0)   Тогда
Состояние("Справочник."+Метаданные.Справочник(к).Идентификатор+" Реквизит: "+Метаданные.Справочник(к).Реквизит(сч).Идентификатор);            
                Ид = Прав(_IDToStr(глМД.ИДРеквизитаСправочника(Метаданные.Справочник(к).Идентификатор,Метаданные.Справочник(к).Реквизит(сч).Идентификатор)),4);    
                
                СписокFIELDIDДляОбработки.ДобавитьЗначение(СокрЛП(Ид),СокрЛП(Ид));
                
                ИмяСправочника=Метаданные.Справочник(к).Идентификатор;
                ИмяРеквезитаС=Метаданные.Справочник(к).Реквизит(сч).Идентификатор;
                Спр=СоздатьОбъект("Справочник."+ИмяСправочника);
                //Если ИмяСправочника = "аисЗапросыМеркурий" Тогда
                //    продолжить;
                //    Предупреждение(ИмяСправочника)
                //КонецЕсли;
                Спр.ВыбратьЭлементы(0);
                Пока Спр.ПолучитьЭлемент()=1 цикл    
                    Если ПустаяСтрока(Спр.ПолучитьАтрибут(ИмяРеквезитаС))=0 тогда
                        ТаблицаФайлДИД.НоваяСтрока();
                        ТаблицаФайлДИД.FIELDID=Ид;
                        СписокСпр=СоздатьОбъект("СписокЗначений");
                        СписокСпр.ДобавитьЗначение("",Спр.ТекущийЭлемент());
                        СписокСпр.ПолучитьЗначение(1,id);
                        ТаблицаФайлДИД.OBJID=_IdToStr(id);                                
                        
                        ТаблицаФайлДИД.IDFIND=СокрЛП(ТаблицаФайлДИД.FIELDID)+СокрЛП(ТаблицаФайлДИД.OBJID);
                        
                        ТаблицаФайлДИД.Содержание=Спр.ПолучитьАтрибут(ИмяРеквезитаС);
                    КонецЕсли;
                КонецЦикла;
                Сообщить("Справочник."+Метаданные.Справочник(к).Идентификатор+" Реквизит: "+Метаданные.Справочник(к).Реквизит(сч).Идентификатор+" FIELDID "+Ид,"i");                    
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;

    
    Для к  = 1 По Метаданные.Документ() Цикл        
        Для сч = 1 По Метаданные.Документ(к).РеквизитШапки() Цикл            
            Если (Метаданные.Документ(к).РеквизитШапки(сч).Тип = "Строка")
            И (Метаданные.Документ(к).РеквизитШапки(сч).Длина = 0)   Тогда
Состояние("Докумет."+Метаданные.Документ(к).Идентификатор+" Реквизит: "+Метаданные.Документ(к).РеквизитШапки(сч).Идентификатор);                    
                Ид = Прав(_IDToStr(глМД.ИДРеквизитаШапки(Метаданные.Документ(к).Идентификатор,Метаданные.Документ(к).РеквизитШапки(сч).Идентификатор)),4);    
                
                СписокFIELDIDДляОбработки.ДобавитьЗначение(СокрЛП(Ид),СокрЛП(Ид));
                
                ИмяДокумента=Метаданные.Документ(к).Идентификатор;
                ИмяРеквезита=Метаданные.Документ(к).РеквизитШапки(сч).Идентификатор;
                Док=СоздатьОбъект("Документ."+ИмяДокумента);
                Док.ВыбратьДокументы();
                Пока Док.ПолучитьДокумент()=1 цикл                    
                    Если ПустаяСтрока(Док.ПолучитьАтрибут(ИмяРеквезита))=0 тогда
                        ТаблицаФайлДИД.НоваяСтрока();
                        ТаблицаФайлДИД.FIELDID=Ид;
                        СписокСпр=СоздатьОбъект("СписокЗначений");
                        СписокСпр.ДобавитьЗначение("",Док.ТекущийДокумент());
                        СписокСпр.ПолучитьЗначение(1,id);
                        ТаблицаФайлДИД.OBJID=_IdToStr(id);    
                        
                        ТаблицаФайлДИД.IDFIND=СокрЛП(ТаблицаФайлДИД.FIELDID)+СокрЛП(ТаблицаФайлДИД.OBJID);
                        
                        ТаблицаФайлДИД.Содержание=Док.ПолучитьАтрибут(ИмяРеквезита);
                    КонецЕсли;
                КонецЦикла;    
                
                
                Сообщить("Докумет."+Метаданные.Документ(к).Идентификатор+" Реквизит: "+Метаданные.Документ(к).РеквизитШапки(сч).Идентификатор+" FIELDID "+Ид,"i");                    
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
26 victuan1
 
22.04.20
15:35
(21) Молодцы, если реализовали возможность внешней БД на SQLite, но вот только у меня версия еще новее чем на скрине (1.03.001.331 СТ), но такой опции почему-то нет.
27 victuan1
 
22.04.20
16:30
(23) Отлично! Вот что у меня получилось https://ibb.co/348CKWv
Теперь понятно, что нужно грохнуть справочник Контур.EDI
28 victuan1
 
22.04.20
17:15
Ну вот, БЛОМ получился 370 Мб, можно жить дальше.
29 victuan1
 
22.04.20
17:16
*БЛОБ
30 victuan1
 
22.04.20
17:17
Но по расчету должен был стать 39 Мб, возможно остался мусор, пробую выгрузку-загрузку теперь.
31 victuan1
 
22.04.20
17:48
(30) Не помогло, размер файла практически не изменился.
32 Cthulhu
 
22.04.20
18:03
(31): натрави мерялку еще раз - посмотри откуда там столько теперь
33 victuan1
 
22.04.20
18:10
(32) Я понял, забыл что я же не весь справочник Контура грохнул, оставил записи за 2020 год. Всё нормально.
34 victuan1
 
22.04.20
18:11
(21) Где можно получить обработку Контура, в которой реализовано возможность держать БД во внешнем хранилище (в базе SQLite)?
35 MarySue
 
23.04.20
00:22
(26) по сути, у тебя версия 1.03.001.33.1  
В последнем разряде третий знак - номер хотфикса.  То есть, после релиза 1.03.001.33 выпустили хотфикс №1.
Такая раньше была нумерация, но её поменяли полгода или год назад.  Теперь там семантическое версионирование  https://semver.org/lang/ru/
Сейчас последняя версия 1.7.3.
36 MarySue
 
23.04.20
01:43
(34) да как обычно, звонишь на ТП, называешь свою организацию, говоришь что надо обновиться, они скинут обновление
в новых версиях можно обновиться прямо из интерфейса по нажатию кнопки, но у тебя старая, нужно вручную ставить
распакуешь архив и скопируешь в него папку с настройками из старого модуля, вот и все дела
37 MarySue
 
23.04.20
01:48
или может не звонить, а написать им надо, как вы там связываетесь обычно с ними
38 victuan1
 
23.04.20
06:39
(37) Уже написал, получил обновление.
39 victuan1
 
23.04.20
06:41
(36) Прямо из интерфейса обновиться не получится, т.к. я модуль адаптировал для нашей нетиповой конфигурации (переписанной в хлам Бух 4.5). Надо будет опять все правки вручную накатывать.
40 Волшебник
 
модератор
23.04.20
07:34
Семёрка ещё сырая...
41 Злопчинский
 
23.04.20
09:59
(40) зато вкусная, натурпродукт... а некоторые суррогаты в красивой обертке только едят... и ругаются что тяжесть в желудке...