|
v7: Необходим быстрый поиск информации в больших CSV файлах | ☑ | ||
---|---|---|---|---|
0
evgpinsk_
01.05.21
✎
13:07
|
Есть прайс в формате CSV площадки onliner.by
В нём 700 тыс позиций. Раз в сутки прайс обновляется. Стоит задача в 1с получать быстрый доступ к цене определённого товара из данного прайса (скорость желательна в пределах нескольких секунд). В прайсе есть столбец "IDтовара" по которому будет осуществляться поиск. Вопрос: Каким образом осуществлять поиск, через какие инструменты? |
|||
1
ДенисЧ
01.05.21
✎
13:08
|
булкой в скуль-сервер и там искать.
|
|||
2
Garykom
гуру
01.05.21
✎
13:13
|
(1) Нахер?
Я бы индекс тупо построил пробежав один раз и вытащив id, и начало/конец символов нужных данных привязав их к id |
|||
3
evgpinsk_
01.05.21
✎
13:14
|
(2) т.е. импортировать данные в dbf файл?
|
|||
4
Garykom
гуру
01.05.21
✎
13:15
|
(3) нафик в регистр запиши если 1Сник
|
|||
5
evgpinsk_
01.05.21
✎
13:15
|
(1) что за булка? )
|
|||
6
Garykom
гуру
01.05.21
✎
13:16
|
||||
7
Garykom
гуру
01.05.21
✎
13:16
|
(6)+ Но не советую разом весь файл в 700к, лучше по 10к порциями
|
|||
8
1CnikPetya
01.05.21
✎
13:17
|
(4) У человека 7ка, какой регистр )
Можно в Номенклатуру добавить периодический реквизит ПоложениеВПрайсе и обновлять его ежедневно. |
|||
9
Garykom
гуру
01.05.21
✎
13:17
|
(8) Эээ я как то отвык уже от 77
|
|||
10
ДенисЧ
01.05.21
✎
13:18
|
(7) Как раз булка-то и нужна, чтобы сотнями тысчк писать, это же не инсерт
|
|||
11
Garykom
гуру
01.05.21
✎
13:18
|
(8) Не не никаких периодических это тормоза
Тогда да лучше dbf с индексом |
|||
12
evgpinsk_
01.05.21
✎
13:19
|
Да, изначально у меня мысли были или DBF или MySql.
Но может ещё есть какие-то несложные инструменты? |
|||
13
Garykom
гуру
01.05.21
✎
13:24
|
(12) экселем открываешь csv и сохраняешь как dbf - это можно автоматизировать
далее средствами 1С навешиваешь индекс и юзаешь |
|||
14
evgpinsk_
01.05.21
✎
13:27
|
(13) CSV-Прайс просто не очень красивый формат имеет.
Цены магазинов идут в одной строке на товар. Сейчас столбцов в прайсе 180штук https://prnt.sc/12cskh0 |
|||
15
trdm
01.05.21
✎
13:31
|
(2) ++
(13) ++ (14) и что? просто нормализуй dbf-ку. |
|||
16
evgpinsk_
01.05.21
✎
13:31
|
В принципе можно ограничиться минимальными ценами ограниченного числа магазинов. Например читать только первые 20 столбцов.
Каким инструментом оптимально экспортировать из Excell в DBF? |
|||
17
Garykom
гуру
01.05.21
✎
13:34
|
(16) дык сам эксель или либреофис и умеют сохранять в dbf
|
|||
18
evgpinsk_
01.05.21
✎
13:39
|
(17) С 2007 офиса уже не сохраняет в DBF
|
|||
19
Garykom
гуру
01.05.21
✎
13:44
|
(18) ыыыы
я на libreoffice давно перешел |
|||
20
Garykom
гуру
01.05.21
✎
13:46
|
короче как бы делал я чтобы было очень шустро для 77
написал бы за полчаса простейшую консольную утилиту на go которая csv2dbf.exe затем запускал бы ее с параметрами из 77 и все |
|||
21
Garykom
гуру
01.05.21
✎
13:48
|
(20)+ самый смак это если файловая то прямо в специально созданную объекту в 1С прямо в dbf табличку писать
ну или для sql 1С 77 аналогично сразу в mssql табличку |
|||
22
Garykom
гуру
01.05.21
✎
13:49
|
(21)+ а искал бы в 1С запросами, они там тупые но вполне шустрые
|
|||
23
Garykom
гуру
01.05.21
✎
13:52
|
(20) даже не полчаса а минут 20 с тестами
1. https://golangs.org/parsing-csv 2. https://github.com/LindsayBradford/go-dbf |
|||
24
Garykom
гуру
01.05.21
✎
13:56
|
(23)+ даже есть готовое но не в ту сторону
https://github.com/lancecarlson/dbfcsv и есть готовое на питоне https://github.com/Kanahiro/dbfConverter в обе стороны |
|||
25
trdm
01.05.21
✎
14:04
|
(24) а питон может компилиться в екзешник.
|
|||
26
Garykom
гуру
01.05.21
✎
14:08
|
(25) там уже скомпилено
но имхо не люблю питон, пришлось вынужденно слегка выучить но не люблю, раздражает |
|||
27
Garykom
гуру
01.05.21
✎
14:09
|
(26)+ для питон это как раньше бейсик был - язык для косячных дебилов
|
|||
28
Garykom
гуру
01.05.21
✎
14:11
|
(27)+ по этой же причине и js с нодой сча бесят, ибо эти косячные просто в веб приперлись и там начали говнокодить
TypeScript в этом плане сильно лучше |
|||
29
trdm
01.05.21
✎
14:36
|
(26) сам не люблю, но иногда это самый оптимальный инструмент.
|
|||
30
Djelf
01.05.21
✎
16:10
|
(0) Лучше конечно конвертировать во что-то более вразумительное чем csv, об этом уже все написали.
Но можно и sqlite прикрутить: https://infostart.ru/public/805029/ (в 7м посте без СМ выложено). |
|||
31
evgpinsk_
01.05.21
✎
16:13
|
(30) В CSV исходный прайс, который даёт площадка
|
|||
32
Djelf
01.05.21
✎
16:27
|
(31) И что из этого следует? Это было очевидно...
Ты прочитал что написано в описании по ссылке в (30)? Быстрее возможно сделать, но скорость запроса будет примерно на 5% выше, т.к. накладные расходы у sqlite очень не высокие. |
|||
33
evgpinsk_
01.05.21
✎
16:37
|
(32) Да, прочитал. Сейчас уже понял в (30) смысл 1го предложения.
sqlite у меня используется кое-где в конфигурации (прямые запросы к справочникам) - скорость изумительная. По ссылке на инфостар - буду смотреть. |
|||
34
ДедМорроз
01.05.21
✎
19:51
|
Csv файл - это файл последовательного доступа,поэтому его нужно хотя бы один раз прочитать весь.
И,если мы его читаем весь,то его можно скорректировать во что-то другое. Я вот в нем логи анализировал,которые за час на несколько гигов набивались,и,нужно сказать,что читаешь и в какую-то sql-базу,так как там потом проще вести анализ. Опять же,если там много колонок с ценами,то можно распределить по отдельным строкам,только нужно будет идентификатор товара придумать. |
|||
35
trdm
02.05.21
✎
10:16
|
(30) Там только dll-ка, примера нет.
|
|||
36
evgpinsk_
02.05.21
✎
10:46
|
(35) Да, жаль )
|
|||
37
Бертыш
02.05.21
✎
12:12
|
(8) Не преувеличивайте коллега. Я в 2003 ем году делал эмуляцию регистра сведений для 7.7 на регистрах накопления
(0) CSV это текст. Грамотно составленное RegExp выражение в скрипте на пайтоне спасёт отца русской демократии. Весь то файл Вам зачем |
|||
38
evgpinsk_
02.05.21
✎
13:07
|
(37) Как минимум нужно быть знакомым с пайтоном ).
поиск в CSV более медленный, чем с использованием индексов |
|||
39
ДедМорроз
03.05.21
✎
00:20
|
(37) если искать только один раз,то да RegExp чем-то поможет,если искать несколько раз,то проще один раз распарсить.
|
|||
40
acanta
03.05.21
✎
09:00
|
А если искать постоянно? То есть использовать csv в качестве базы данных (лог файл, дописывается в конец) и отчеты собрать по нему?
|
|||
41
Mikeware
03.05.21
✎
11:04
|
(40) "дописывается в конец", и "собрать 1 отчет в несколько дней" (ну или "изредка поискать") - это не совсем "БД". Хотя некоторым критериям ("структурирована", "соответсвует схеме") соотвествует БД, но по "типизации", "произвольному доступу к полям" - не соотвествует. Из-за этого сложнее построить лополнительне структуры для улучшения поиска (индексы). поэтому "постоянный поиск" по цсв - плохая идея.
|
|||
42
acanta
03.05.21
✎
11:10
|
(41) но эксель открывает файлы csv и позволяет использовать пусть не все, но какие то механизмы обработки файлов баз данных...
|
|||
43
Mikeware
03.05.21
✎
11:19
|
(42) когда "эксель открывает файлы csv" ("импортирует", если быть точным) - он проделывает туеву хучу дополнительной работы. Например, разделяет "по полям", и "типизирует". Именно это приводит относительно регулярную текстовую структуру к регулярной таблице.
|
|||
44
acanta
03.05.21
✎
11:21
|
В чем разница между импортом екселя и булк инсертом sql?
|
|||
45
Mikeware
03.05.21
✎
11:24
|
(44) как посмотреть. с однй стороны ее почти нет (текст преобразовывается в регулярную таблицу), с другой разница большая в скорости, в объеме возможных преобразований, и полученном результате.
|
|||
46
acanta
03.05.21
✎
11:43
|
Но в случае екселя результат в оперативной памяти и возможно, во временном файле. А в случае sql только файл. Проблема в том, что оперативная память с наведением красоты медленнее или в том что исходный файл читают дважды и разные получатели?
|
|||
47
Mikeware
03.05.21
✎
11:50
|
(46) "Но в случае екселя результат в оперативной памяти и возможно, во временном файле." а возможно, и в постоянном.
"А в случае sql только файл." - а в случае sql в файл это попадет только после записи. но даже запись в файл не мешает висеть в кэше. "Проблема в том, что оперативная память с наведением красоты медленнее или в том что исходный файл читают дважды и разные получатели?" - видимо, проблема в ДНК... |
|||
48
acanta
03.05.21
✎
13:40
|
Или в том, в каком возрасте и в каком объеме изучать английский, чтобы то, что написано нашими программистами на современных языках программирования, имело хоть какой-то смысл?
|
|||
49
Alex_
Alexsin_2020 03.05.21
✎
13:49
|
можно на шарпе написать (будет время пошарю у себя я уже делал себе) но поиск в текстовых файлах
создаем индексный файл и ищем но в любом случае боюсь что в пределах 1 секунды не сможет найти насколько помню 10 тысяч записей в пределах где то 30 сек ищет |
|||
50
Alex_
Alexsin_2020 03.05.21
✎
13:50
|
это я делал для загрузки в 1С данных из сторонних источников так как 1С обычно долго думала
|
|||
51
acanta
03.05.21
✎
13:57
|
Вот я не понимаю смысла в полнотекстовом поиске в 1с. У клиентов после третьего повреждения отключила. По подстроке искать в нескольких колонках с представлениями и фильтровать по результатам динамический список?
Я понимаю, что ексель это может и это очень круто.. |
|||
52
ДедМорроз
03.05.21
✎
13:59
|
Excel определяет тип колонки на лету,а для создания таблицы его нужно указать,и если в разных строках есть разные типы,то для sql это очень печально.
Я делал базу данных на текстовых файлах,для создания индекса нужно запомнить только позиции начала строк в файле,а также выбрать целевые поля. Если индекс работает эффективно и мы выбираем всего несколько записей,то распарсить строку с начала до перевода строки-это не критично по скорости. При желании,можно даже допустить добавление строк в конец файла. Если предположить,что наличие в начале строки специальног символа # означает,что строка игнорируется,то можно даже делать редактирование - если новая строка влазит по месту старой,то может остаться хвост комментария,а если не влазит,то она превращается в комментарий и новое значение пишется или в конец или на место комментария подходящего размера. |
|||
53
Alex_
Alexsin_2020 03.05.21
✎
14:02
|
(0) если не затруднит напишите какой разделитель, и номер столбца где находится поле по которому ищем
|
|||
54
Alex_
Alexsin_2020 03.05.21
✎
14:02
|
+(53) а так же имена столбцов которые имеются в файле
|
|||
55
evgpinsk_
08.05.21
✎
09:56
|
(53) Вопрос ко мне?
Разделитель и поле поиска ведь может быть любым, это большого влияния на суть задачи не оказывает |
|||
56
ptiz
08.05.21
✎
10:24
|
(16) Зачем тебе "из Excel в DBF", если можно из твоего файла сразу dbf создать средствами 7.7?
|
|||
57
evgpinsk_
08.05.21
✎
10:51
|
(56) Как именно?
|
|||
58
ptiz
08.05.21
✎
15:41
|
(57) А в чем затык? Чтение текста - через СоздатьОбъект("ADODB.Stream"). DBF создается с помощью СоздатьОбъект("XBase").
|
|||
59
Кирпич
08.05.21
✎
15:53
|
(57) Найди программиста и он тебе за часик сделает. Много денег не возьмет. Только не спрашивай, где искать программиста.
|
|||
60
evgpinsk_
08.05.21
✎
15:59
|
(56) Не очень красиво построчно читать и заносить в dbf. 700 тыс позиций и 185 столбцов не очень быстро отрабатываются
|
|||
61
trdm
08.05.21
✎
16:06
|
Сделал бы уже и забыл.
|
|||
62
evgpinsk_
08.05.21
✎
16:13
|
||||
63
acanta
08.05.21
✎
16:14
|
64536? размерность поля номер строки в ДБФ
|
|||
64
evgpinsk_
08.05.21
✎
16:15
|
(63) Нет. 48806 строк записалось. И затем ошибка
|
|||
65
acanta
08.05.21
✎
16:19
|
А сколько гигабайтов?
|
|||
66
evgpinsk_
08.05.21
✎
16:22
|
(65) 256Мб если CSV файл
этот же файл, сохранённый в xlsx - 91МБ |
|||
67
acanta
08.05.21
✎
16:25
|
какие поля по размеру в ДБФ и сколько получилось в записанном ДБФ файле?
|
|||
68
Кирпич
08.05.21
✎
16:26
|
(66) Выложи файлик куда нибудь. Я тебе запилю конвертер. Один хрен дождь льёт весь день.
|
|||
69
Кирпич
08.05.21
✎
16:27
|
(66) А чо ты через excel не сохраняешь?
|
|||
70
evgpinsk_
08.05.21
✎
16:28
|
(67) В зависимости от количества столбцов, которые читаю. Т.е. ограничение идёт на размер самого dbf файла.
На момент возникновения ошибка файл процесса 1с занимает 1гб в оперативной памяти |
|||
71
acanta
08.05.21
✎
16:30
|
ДБФ может записывать на диск сразу построчно, зачем в памяти?
|
|||
72
evgpinsk_
08.05.21
✎
16:30
|
(69) Насколько я понимаю: Ексель не сохраняет в dbf. До 2007 офиса сохранял, но он до 65к строк только умел читать
|
|||
73
Кирпич
08.05.21
✎
16:31
|
(62) А ты всё то не тащи в dbf. Только код(ну по чем искать потом) и номер строки в файле. Потом ищешь по коду в маленькой dbf и переходишь на нужную строку в файле.
|
|||
74
Кирпич
08.05.21
✎
16:32
|
файл читай через ADO (там даже драйвер для csv должен быть)
|
|||
75
evgpinsk_
08.05.21
✎
16:33
|
(73) Но почему ошибка при больших объёмах чтения всё-таки вылазит? Ради интереса понять. Вот код:
https://prnt.sc/12odpon |
|||
76
evgpinsk_
08.05.21
✎
16:33
|
(74) Я и читаю через ADO, правда читаю xlsx но это не важно
|
|||
77
trdm
08.05.21
✎
16:34
|
(62) Скинь плз файло на почту, поиграюсь...
|
|||
78
Кирпич
08.05.21
✎
16:35
|
(75) нахрен там чота понимать. это всё никому не нужное. надо задачу решать
|
|||
79
H A D G E H O G s
08.05.21
✎
16:36
|
Ну 2 Гб файл превысил или сколько там на dbf ?
|
|||
80
evgpinsk_
08.05.21
✎
16:36
|
(77) CSV файл https://dropmefiles.com/9wccW
|
|||
81
evgpinsk_
08.05.21
✎
16:36
|
(79) так CSV файл текстом идёт всего 250Мб
|
|||
82
evgpinsk_
08.05.21
✎
16:37
|
(73) Да, такой вариант можно реализовать
|
|||
83
acanta
08.05.21
✎
16:37
|
||||
84
H A D G E H O G s
08.05.21
✎
16:37
|
(81) Там в dbf поля фиксированной длины и на них ты получишь избыточность
|
|||
85
trdm
08.05.21
✎
16:37
|
(75) Не стоит так делать, надо делать 2 dbf-ки, одну со структурой
code_t,code_m,prise другую code_m,title_m |
|||
86
trdm
08.05.21
✎
16:38
|
(84) ++
|
|||
87
H A D G E H O G s
08.05.21
✎
16:39
|
Вы какой-то шлабудой занимаетесь.
|
|||
88
trdm
08.05.21
✎
16:48
|
+(85) а, нет, посложнее нужна структурка, но смысл тот же.
|
|||
89
trdm
08.05.21
✎
16:49
|
в зависимости от требуемой аналитики. но ничего сложного.
|
|||
90
evgpinsk_
08.05.21
✎
16:52
|
(84) Понял.
(85) А в чём плюс двух файлов? |
|||
91
trdm
08.05.21
✎
16:53
|
(90) Нормализация базы данных. погугли.
|
|||
92
evgpinsk_
08.05.21
✎
16:54
|
Два файла только решить проблему размера dbf файла на 2Gb и всё? Скорость чтения ведь будет одинакова
|
|||
93
trdm
08.05.21
✎
17:00
|
это от задачи зависит. понятия не имею, какая тетализация нужна.
|
|||
94
hhhh
08.05.21
✎
17:41
|
(92) ну 700 тыс строк - это детский сад, мизер, там максимум 1 GB дотянешь, и то чисто теоретически.
|
|||
95
Кирпич
08.05.21
✎
18:13
|
(92) вот наговнокодил https://cloud.mail.ru/public/kbdr/R2Wz7Nays
там exe и исходники кидаешь на csv2id.exe csv файл и рядом появляется маленький csv, в котором id товара и его смещение в большом csv юзай этот маленький csv как хошь. хоть в dbf хоть куда. А большой читай через ADO Stream |
|||
96
H A D G E H O G s
08.05.21
✎
18:18
|
(95) Ну елки - палки. Ну и где интерфейс?
|
|||
97
H A D G E H O G s
08.05.21
✎
18:24
|
1) bulk insert в таблицу SQL NewData
2) Сравнение с таблицей OldData 3) Дельту в таблицу DiffData 4) Удаление таблицы OldData 5) Переименование таблицы NewData в OldData |
|||
98
evgpinsk_
08.05.21
✎
18:36
|
Подскажите ещё, туплю и не могу понять как правильно создавать индексный файл?
В чём отличие команд "ДобавитьИндекс" и "СоздатьИндексныйФайл"? Как нужно исправить код : ДБФ = СоздатьОбъект("xbase"); ДБФ.ДобавитьПоле("KodOnliner","S",20,1); ДБФ.ДобавитьПоле("minCost","N",12,2); ДБФ.ДобавитьИндекс("KodOnliner", "NAME",1,0,0); ДБФ.СоздатьФайл("d:\33.dbf","d:\33.cdx"); недокументированная ошибка вылазит |
|||
99
evgpinsk_
08.05.21
✎
18:41
|
(95) Мне наверное будет проще в 1с в цикле чтения CSV файла писать данные в два отдельных DBF файла. В одном будет id товара, а в другом его цены.
Лимит в 2гб не получу |
|||
100
evgpinsk_
08.05.21
✎
18:44
|
(98) С ошибкой разобрался, в последнем параметре была :
ДБФ.ДобавитьИндекс("KodOnliner", "NAME",1,0,""); |
|||
101
acanta
08.05.21
✎
18:47
|
Там еще авто сохранение было.
В сдх индексы все в одном файле, а в фокспро в отдельных. |
|||
102
Djelf
08.05.21
✎
20:29
|
(96) Интерфейс это ерунда, при рабочем решении!
Кирпич нарисовал индекс, для этого, частного случая, в отдельном csv файле. Этот вариант вполне работоспособен, 1С же же в 3й версии индексов своих логов подобный и применила. И он должен быть быстрее раз в 10-100 любой конвертации в сторониие форматы! |
|||
103
Кирпич
08.05.21
✎
20:38
|
(102) Не очень работоспособен. Чота ADO Stream кажись грузит весь файл в память и читать строку не получатся. Пускай уже грузит в dbf :) Разве что грузилку в dbf написать в отдельном exe(ради быстродействия)
|
|||
104
acanta
08.05.21
✎
21:02
|
Так к концу года глядишь и файловую версию 1с 8.3 на прямые запросы можно будет...
|
|||
105
acanta
08.05.21
✎
21:03
|
Простите за глупые вопросы, у них что, файловая база в csv, а индексные файлы в кеше?
|
|||
106
Вафель
08.05.21
✎
22:26
|
В любом случае чтобы получить строку по номеру нужно весь файл в память загрузить
|
|||
107
Вафель
08.05.21
✎
22:26
|
И каждый раз придётся это заново делать для каждого юзера
|
|||
108
Garykom
гуру
08.05.21
✎
22:49
|
(106) Зачем? Можно же файл считывать с нужной позиции символов-байт
Но да надо иметь внешний индекс с какой позиции нужная строка и длина строки |
|||
109
evgpinsk_
09.05.21
✎
00:30
|
(102) Не совсем понял смысл использования скрипта exe для разделения одного большого CSV файла на два маленьких. Ведь всёравно для поиска данные нужно закинуть или в DBF или в другую баду данных, где через индекс можно будет производить быстрый поиск
|
|||
110
Garykom
гуру
09.05.21
✎
00:46
|
(109) Хочешь тупую идею?
Совсем тупую но вполне рабочую. Банально одним проходом подели свой csv на 700 тысяч файлов, в каждом одна строка А имя файла это твой id по которому искать будет банально, просто прочитать файл с этим именем |
|||
111
Garykom
гуру
09.05.21
✎
00:47
|
(110)+ Тут конечно ограничение файловой системы может всплыть но маловероятно, миллионы вроде там ограничения файлов если не больше в одном каталоге
|
|||
112
evgpinsk_
09.05.21
✎
00:58
|
(110) По большому счёту любой формат хранения данных подходит, который позволяет искать через индекс.
Я уже реализовал построчное чтение xlsx в dbf через ADODB Читать сразу CSV файл через ADODB у меня не получилось, и есть неудобная ручная операция - сохранение CSV в XLSX |
|||
113
Garykom
гуру
09.05.21
✎
01:49
|
(112) Операции со строками и текстовыми файлами самые быстрые
Это так к сведению Поэтому просто попробуй (110) |
|||
114
Кирпич
09.05.21
✎
10:01
|
(106) Не строку по номеру, а смещение строки в файле. Но это работает, если есть средства перемещения по файлу.
Ну как бы эта задача решается загрузкой в дбф трёх полей. Просто с толку сбило недельное сидение автора над задачей. Я уж подумал ему все данные нужны или медленно работает или хрен знает почему он не хочет тупо грузить в дбф. |
|||
115
trdm
09.05.21
✎
10:07
|
(112) Кажется есть провайдер, который может прямо из csv читать.
и не нужна прокладка. https://www.connectionstrings.com/textfile/ |
|||
116
Garykom
гуру
09.05.21
✎
10:25
|
(114) просто ТС не программист а не пойми что
над смешной задачкой которая за пару-тройку часов решается сидит хз сколько |
|||
117
evgpinsk_
09.05.21
✎
11:42
|
(116) А все кто задаёт вопросы на мисте должны быть программистами, а если нет значит - "не пойми что" ?
п.с. в (110) было менее глупо |
|||
118
acanta
09.05.21
✎
11:48
|
Еще раз для программистов. В 7.7 дбф версии иногда случались сбои. Чаще всего они исправлялись методом переиндексации. В sql версии этих проблем не было.
В 8 ке как версии файловой, так и серверной случаются сбои и они чаще всего исправляются чисткой кэша. Следует ли из этого вывод, что в кэше 1с8 хранятся индексы или какая то их часть, как в файловой так и в серверной версии? |
|||
119
Djelf
09.05.21
✎
12:17
|
В продолжение поста в (30).
260мб csv -> 312мб sqlite, меньше минуты требуется
|
|||
120
dmitryds
09.05.21
✎
12:23
|
(0) вот это срач... а всего лишь один запрос сделать, как написано в (1)
https://docs.microsoft.com/ru-ru/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-ver15 |
|||
121
trdm
09.05.21
✎
14:21
|
(120) не, в данном случае хрень.
|
|||
122
trdm
09.05.21
✎
14:25
|
(118) > В sql версии этих проблем не было.
повезло тебе, а у меня раз SQL БД навернулась. С тех пор новые документы выгружаю сразу после записи.. |
|||
123
Sysanin_1ц
09.05.21
✎
14:46
|
(0) Панду ТС никто не предлагал? Если нет, то я буду первым
|
|||
124
H A D G E H O G s
09.05.21
✎
15:36
|
SQL
Вставка - 50 секунд SELECT top 1 * FROM [tmp].[dbo].[catalog_prices] where [ID]='2326434' 32 мс CREATE UNIQUE INDEX Priceidx ON catalog_prices (id); 103 мс SELECT * FROM [tmp].[dbo].[catalog_prices] where [ID]='2326434' 1 мс |
|||
125
Djelf
09.05.21
✎
15:53
|
(124) Те же яйца что в (119), только в профиль!
Выборка по индексу что так, что сяк будет 0-3 мс, и это не существенно. Но есть и разница - на MSSQL придется что-то делать, а на SQLite нет! Это небольшой профит, но он есть... |
|||
126
trdm
09.05.21
✎
17:35
|
(124) (125) Там в cvs все равно ненормализованная таблица.
Затяните в лоб - запросы на извлечение будут сложными. Нужна предобработка. |
|||
127
Djelf
09.05.21
✎
20:27
|
(126) На таком объеме sqlite хорошо работает и без предобрабоки и без дедупликации.
Можно и это сделать, пару минут наверное займет (запрос уникальных значений у меня 5с занимает по любой колонке, ну +накладные, ну +несколько колонок, ну... за пару минут сработает)... Но зачем? 300+ метров для sqlite не проблема, и в данном решении можно и без дедупликации обойтись |
|||
128
Кирпич
09.05.21
✎
20:49
|
У меня на ноуте на создание файлика с нужными данными уходит <4 сек и <50 мс на поиск нужной строки в этом файлике тупым перебором(это открытие файлика, поиск и закрытие). Нафиг тут sql серверы не нужны.
|
|||
129
evgpinsk_
09.05.21
✎
22:36
|
(119) Пытался гуглить, но так и не понял, как этот код выполнять в 1с? (т.е. из csv быстро загнать данные в mysql)
либо что для меня лучше - из csv в dbf если это делать средствами 1с через ADODB (построчно читать данные) - очень долго получается п.с. ссылки на предыдущей странице на скрипт на гитхабе (csvTOdbf) - он у меня не отрабатывает мой конкретный CSV файл - на выходе dbf получается поломанным |
|||
130
hogik
10.05.21
✎
02:40
|
«для меня лучше - из csv в dbf»(с)
Самый быстрый способ: 1) Создать пустой DBF нужной структуры в среде 1С. 2) Вызвать программу на FoxPro в которой удаляется CDX и выполняется APPEND FROM. http://www.foxclub.ru/rhproject/project/html/c426861f-e5ef-44ae-96a6-8dbc7a4a2ad5.htm 3) Создать CDX в среде 1С. Пример закачки файла для «Проверка по списку недействительных российских паспортов». http://xn--b1afk4ade4e.xn--b1ab2a0a.xn--b1aew.xn--p1ai/info-service.htm?sid=2000 |
|||
131
hogik
10.05.21
✎
02:40
|
parameters p1
local p,t,s,f,r,k set debug off close all on escape do figa set sysmenu off set safety off set collate to "RUSSIAN" set optimize off t=chr(13)+chr(10)+"Для продолжения нажмите любую клавишу..." f="list_of_expired_passports.csv" r="Passport" modify window screen title "Загрузка Серия+Номер" font "Courier",8 noclose if vartype(p1)<>"C" then ? "Вызов: foxpass <Каталог>" wait t return 1 endif p=alltrim(p1) p=p+iif(right(p,1)="\","","\") if file(p+f)=.F. then ? "Нет файла: "+p+f wait t return 1 endif if file(p+r+".DBF")=.F. then ? "Нет файла: "+p+r+".DBF" wait t return 1 endif if file(p+r+".CDX")=.T. then delete file (p+r+".CDX") endif s=seconds() ? "Обрабатывается: "+p+f use (p+r) exclusive zap append from (p+f) fields Code delimited with tab as 1251 k=reccount() use ? "Загружено записей: "+alltrim(str(k,20,0)) ? "Время выполнения: "+alltrim(str((seconds()-s)/60,20,0))+" мин." wait t return 0 ********************************************************************** function figa endfunc ********************************************************************** |
|||
132
Garykom
гуру
10.05.21
✎
02:48
|
(130) (131) приколист где для начала он foxpro возьмет с учетом лицензии?
|
|||
133
hogik
10.05.21
✎
05:00
|
(132)
«приколист где для начала он foxpro возьмет с учетом лицензии?»(с) Например, возьмёт runtime library для FoxPro и один EXE (исходный текст ниже) файл позволяющий выполнять исходные тексты. parameters p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 local f if !empty(p0) f=upper(alltrim(p0)) f=f+iif(right(f,4)==".PRG","",".PRG") if file(f) f=substr(f,1,len(f)-4) compile &f do case case empty(p1) do &f case empty(p2) do &f with p1 case empty(p3) do &f with p1,p2 case empty(p4) do &f with p1,p2,p3 case empty(p5) do &f with p1,p2,p3,p4 case empty(p6) do &f with p1,p2,p3,p4,p5 case empty(p7) do &f with p1,p2,p3,p4,p5,p6 case empty(p8) do &f with p1,p2,p3,p4,p5,p6,p7 case empty(p9) do &f with p1,p2,p3,p4,p5,p6,p7,p8 otherwise do &f with p1,p2,p3,p4,p5,p6,p7,p8,p9 endcase endif endif |
|||
134
evgpinsk_
10.05.21
✎
10:20
|
Подтягивать ещё foxpro не очень бы хотелось. У меня всё работает, dbf создаю через ADO читая xls
Есть два нюанса, которые не нравятся и которые не знаю как решить: 1) Сейчас руками сохраняю из CSV в XLSX (читать напрямую через ADO файл CSV не получается) 2) Время выполнения чтения первых 7ми столбцов xlsx файла - 250 секунд, что терпимо. Но если ещё читать и остальные 170 столбцов - очень долго простым перебором |
|||
135
trdm
10.05.21
✎
10:58
|
(134) парси "в лоб". Без Excel. Ваще быстрее будет и не надо буде извращаться. И лишние инструменты отпадут и быстрее будет.
|
|||
136
evgpinsk_
10.05.21
✎
11:25
|
(135) Возможно да, но опять много времени тратить на переделку не хочется ), когда уже есть почти работающий инструмент
|
|||
137
Garykom
гуру
10.05.21
✎
12:23
|
(136) говно а не инструмент пока
а насчет "опять много времени тратить" еще раз повторю твоя задачка нормальным прогом решается за 2-3 часа |
|||
138
Garykom
гуру
10.05.21
✎
12:36
|
(137)+ так как у тебя 77 то значит винда
а значит читать через http://www.script-coding.com/WSH/FileSystemObject.html#3.24. OpenTextFile или OpenAsTextStream если CSV без лишних разделителей ("," или ";") внутри полей то далее простейше и делай что хочешь, хочешь индекс делай в DBF а читай из CSV или все в DBF перегоняй |
|||
139
evgpinsk_
10.05.21
✎
12:41
|
(137) В чём конкретно говно ? )
Способ решения вполне нормальный выбран: Через ADO читаем исходный файл с данными и закидываем его в DBF, далее по индексу поиск нужно товара в прайсе занимает милисекунды. Проблемы две: время создания DBF файла через ADO 250 секунд если читать по минимуму только первые 8 столбцов (и критически долго - если все столбцы) Приходится руками конвертировать из CSV в XLSX Решить эти две проблемы программисту занимает не 2-3 часа - а минут 5 :) и в теории это мне известно, вараинт А) либо вместо dbf использовать SQLlite как в примере (119), но гугл не даёт мне конкретного примера какой ситнтакис в самой 1с этого кода из (119): DROP TABLE IF EXISTS vtPrice; CREATE VIRTUAL TABLE vtPrice USING csvfile('d:\temp\price\catalog_prices_2021-05-08_13_05_50.csv',0,1); ATTACH 'd:\temp\price\catalog_prices_2021-05-08_13_05_50.db3' as Price; вариант Б) использовать сторонню софтину CSVtoDBF - но не смог найти через гугл чтото работающее: либо платное, либо кряки с вирусами. |
|||
140
evgpinsk_
10.05.21
✎
12:45
|
(138) Помню что полгода назад читал CSV файлы "в лоб"
и помню что тоже много нюансов вылазило, и количество строчек кода для лечения всех этих нюансов помню было точно не меньше 10-20. Не хочется начинать пробовать чтобы опять упереться в какойто нюанс и сидеть над ним несколько часов. Если не найду работаюший скрипт CSVtoDBF или не получу подсказку-пример как закинуть CSV в SqLite (а это было бы полезно и для общего развития) тогда уже буду думать по смене принятого алгоритма решения |
|||
141
Djelf
10.05.21
✎
12:48
|
(140) Да я же тебе все запросы в sqlite в (119) написал. Это все работает.
Или тебе все это в код на 1С нужно обернуть? Там же простые запросы по очереди, ничего сложного... |
|||
142
evgpinsk_
10.05.21
✎
12:49
|
(138) Проблема в том, что инструменты которые по этой ссылке для меня не знакомы. И если знающему эти инструменты их приминение занимает 1-2 минуты
то для меня сначала нужно будет потратить несколько часов на их изучение. ну не программер я ) Трачу пару часов в неделю на решение каких то задач, т.к. мне это интересно. Но уровень знаний в большей степени только на уровне базового 1с |
|||
143
evgpinsk_
10.05.21
✎
12:50
|
(141) Сами запросы в (119) мне понятны. Но да, к сожалению мне не понятно как это закинуть в 1с.
Примеров гугл на даёт ( |
|||
144
evgpinsk_
10.05.21
✎
12:54
|
И по ссылке (30) пример реализации "CSVtoDBF для больших массивов данных" в 1с тоже не доступен. Потратил час времени на поиск в гугле но зря
|
|||
145
mistеr
10.05.21
✎
12:54
|
700К это фигня, если честно. Любая in-memory БД и будет летать при наличии памяти. SQLite тоже справится.
А "пределах нескольких секунд" справится даже справочник в основной базе. Ночью обновляешь, днем читаешь. Иля я проблемы не понимаю. |
|||
146
mistеr
10.05.21
✎
12:55
|
Если проблема прочитать CSV и залить в справочник, то найма программиста, за 2-3 ч. сделает.
|
|||
147
mistеr
10.05.21
✎
12:55
|
(146) *найми*
|
|||
148
evgpinsk_
10.05.21
✎
12:57
|
(146) Понимаю что иногда читается между строк, но "прочитать CSV и залить в справочник" я и сам сделал.
Но штатное решение занимает не один десяток минут на чтение всего CSV файла размером 267МЕГАбайт |
|||
149
mistеr
10.05.21
✎
12:59
|
(148) Странно, но допустим. Это проблема? Раз в сутки можно и 20 минут выделить на это.
|
|||
150
evgpinsk_
10.05.21
✎
13:02
|
(149) Да, т.к. читать этот файл мне хотелось бы дважды в сутки и в рабочее время. Читается это в специальном сеансе Робота, где крутится 1с.
И если 1с зависает на 20-30 минут монопольно на чтение CSV файла, то в этом момент не работаю другие задачи (например чтения оналйн заявок с интернет-магазина) |
|||
151
Djelf
10.05.21
✎
13:10
|
(142) Тогда понятно...
Ну ладно, вот тебе код на 1С
И код для консоли sqlite3.exe. Можешь в батник завернуть, как - ищи сам.
Без моего расширения файл, загрузить можно, но исходник в кодировке 1251, а sqlite работает в utf8, потребуется перекодирование, а у меня оно встроено. |
|||
152
evgpinsk_
10.05.21
✎
13:15
|
(151) Спс, изучаю
|
|||
153
Djelf
10.05.21
✎
13:18
|
(152) А 1sqlite и sqlite3_mod_csv_03 забирай отсюда https://cloud.mail.ru/home/1sqlite/
|
|||
154
evgpinsk_
10.05.21
✎
13:55
|
(153) Может быть из-за старой версии 1sqlite?
База.РазрешитьЗагрузкуРасширений(1); {Обработка.ЗагрузкаДанныхОнлайнера.Форма.Модуль(16)}: Поле агрегатного объекта не обнаружено (РазрешитьЗагрузкуРасширений) п.с. по ссылки на маил.ру - нет файлика |
|||
155
Djelf
10.05.21
✎
14:58
|
(154) Конечно из-за старой, и очень-очень старой! В оригинальной версии Орефкова загрузка расширений была задумана, но не работает.
Вот правильная ссылка https://cloud.mail.ru/public/9znr/ZJ6ULE9aR |
|||
156
Вафель
10.05.21
✎
15:08
|
Мускул поднять. Он умеет балк лоад из цвс
|
|||
157
evgpinsk_
10.05.21
✎
15:20
|
(155) Да, у меня была 1.0.2.3
Более свежая 1.0.2.6 решила проблему |
|||
158
evgpinsk_
10.05.21
✎
15:22
|
За 37 секунд загружается CSV размером 700Мб в Sqlite базу
Сейчас буду изучать как его читать ) |
|||
159
Djelf
10.05.21
✎
15:43
|
(158) Это самое простое...
Создаем уникальный индекс на код товара и запрос в ТЗ. Тут есть заморочки с именами колонок! Имя колонки из-за того что в нем пробелы - в квадратных скобках, а тип значения колонки [ID Товара] - строка, поэтому в одинарных кавычках. |
|||
160
mistеr
10.05.21
✎
15:53
|
(159) Поскольку ТС не совсем программист, нужно отдельно отметить, что индекс создается один раз после загрузки.
А параметры умеет это расширение? |
|||
161
Djelf
10.05.21
✎
15:57
|
(160) Таблица же дропается перед загрузкой, проблем не будет, но можно написать и так:
Запрос.ВыполнитьЗапрос("CREATE UNIQUE INDEX IF NOT EXISTS [idxGoods] ON [Price]([ID товара]);"); Какие-то параметры умеет https://infostart.ru/public/805029/ там написано что умеет. |
|||
162
evgpinsk_
10.05.21
✎
16:02
|
(160) Да, заметил ). Через Попытку Исключение
обрабатываю. И ещё чисто теоретический вопрос ради интереса: в самом CSV файле нет отдельного столбца, которое нужно индексировать для поиска. индекс нужно строить по части поля столбца, который содержит путь к файлу: http://catalog.onliner.by/cartridges/xerox_compat/0006r01179 и индексируемым значением для поиска будет текст за последним слешем: "0006r01179" простой вариант решения - сделать предобработку CSV файла, выделив в нём это нужное значение части поля в отдельный столбец. Вопрос- так и делать , либо движок sqlite может решить эту задачи своими средствами? |
|||
163
mistеr
10.05.21
✎
16:05
|
(161) Я имел в виду, что не при каждом поиске индекс создавать. :)
|
|||
164
mistеr
10.05.21
✎
16:08
|
(162) Добавить колонку, сделать UPDATE SET <колонка> = <выделить нужную часть>
|
|||
165
evgpinsk_
10.05.21
✎
16:11
|
(163) Так Djelf это понял и привёл пример как анализировать есть ли созданный индекс
(164) Вопрос как выделить нужную часть. Нужно взять всё то правее относительного последнего / в анализируемой строке. sql язык умеет найти эту последнюю часть текста? |
|||
166
Djelf
10.05.21
✎
16:12
|
(163) Индекс же в файле хранится, т.е. в движке sqlite, а не в обвязке для 1C - 1sqlite/
(162) Может, движок sqlite поддерживает индексы на основе выражения, но я этот вариант не пробовал. Может сработать, а может и нет. Выделение части из строки не очень простой вариант индекса. Лучше отдельный столбец и в него что-то нужно запихнуть. Либо, не парится, а искать по like, это вероятно не будет слишком медленно... |
|||
167
evgpinsk_
10.05.21
✎
16:17
|
в теории like может выдать лишние варианты поиска.
Значит буду делать предобработку CSV |
|||
168
mistеr
10.05.21
✎
16:30
|
(165) Нет, последнюю не получится, только первую. Лучше при загрузке выделить.
|
|||
169
Djelf
10.05.21
✎
16:30
|
(167) У тебя семь пятниц на неделе, сначала ты пишешь "В прайсе есть столбец "IDтовара" по которому будет осуществляться поиск."
Теперь у тебя "индекс нужно строить по части поля столбца, который содержит путь к файлу:" Нельзя настолько менять условия задачи по ходу дела! Интересно сколько времени у тебя займет предобработка твоего 700метрового csv... Видимо задача стоит не ускорять загрузку файла, а наоборот - замедлять! ;) |
|||
170
Djelf
10.05.21
✎
16:35
|
(168) Это в больших базах sql не очень сложно, можно и в sqlite например так: https://github.com/mayflower/sqlite-reverse-string
Т.е. реверсируем строку, ищем разделитель, вычитаем, дополняем, выкусываем. Бинго! Либо пишем свой велосипед... P.S. давно уже перестал удивляться почему поиск "с начала" везде сделан, а "поиск с конца" почти нигде. |
|||
171
mistеr
10.05.21
✎
16:38
|
(170) Либо просто загружаем нормальные данные :)
|
|||
172
Djelf
10.05.21
✎
16:39
|
И!!! (162) Код товара в файле уникален. А вот код "0cb435a" в строке "http://catalog.onliner.by/cartridges/hp_compat/0cb435a" уникален?
Точно-точно уверен? Ты генерацию этого кода у onliner.by смотрел? В техподдержку писал? Они точно гарантируют уникальность? |
|||
173
evgpinsk_
10.05.21
✎
16:47
|
(169) Ну изначально я ведь не знал каким будет итоговое решение )
Поэтому и выразился фигурально про ID товара Да, уже понимаю, что предобработка тоже время кушать будет, если в лоб решать ) (172) Да, эта часть поля тоже будет уникальным индексом. Я в DBF файл выгружал и по нему строился индекс. И мой весь движок работы с онлайнером построенном именно на этом индексе (последняя часть html строки товара) а IDтовара есть только в этом CSV файле и парсить в других местах я его не могу. |
|||
174
Arbuz
10.05.21
✎
17:07
|
(170) Ух ты ж! Жемчужина в навозе... А есть собранное? Там же что-то с кодировками в 1C и sqlite?
|
|||
175
Djelf
10.05.21
✎
17:54
|
(174) Маловато что-то жемчужин в этом * завалялось, подсыпем еще чуток...
|
|||
176
evgpinsk_
10.05.21
✎
19:37
|
(175) Это круто.
Но не пойму что за функция Rtrim (par1,par2,par3,par4) ? Классически она отсекает пробелы справа в передаваемом параметре и у неё один параметр |
|||
177
evgpinsk_
10.05.21
✎
19:50
|
(176) Ошибся, правильно так:
Rtrim (par1,par2) но всё равно не понятно |
|||
178
Djelf
10.05.21
✎
20:08
|
(177) Это магия sql! rtrim не так работает...
|
|||
179
evgpinsk_
10.05.21
✎
20:53
|
(178) "у меня там косячёк нашелся, без указания этих двух пустых параметров, значения в колонках кое-где съезжают ;("
Добавление пустых параметров не помогает. Съезжают значения в колонках из-за числовых значений, в которых есть знак запятой. Если запятую поменять на точки, то дробная часть числа не съезжает. Сейчас буду пробовать решить через замену в числовых столбцах запятой на точку |
|||
180
Djelf
10.05.21
✎
21:11
|
(179) Ладно, тогда SpecialEdition с отключенной запятой для разделителя: https://cloud.mail.ru/public/yvfM/hHZQEV13a
|
|||
181
evgpinsk_
10.05.21
✎
21:17
|
(180) Работает )
Параллельно загуглил как через PowerShell производить автозамену в текстовых файлах |
|||
182
Djelf
10.05.21
✎
21:38
|
(180) Этот модуль отсюда взят http://www.ch-werner.de/sqliteodbc/
Я там много всякого наковырял, видимо не тестировал с разделителем запятая, либо не попадались такие файлы... Давно дело было. Оригинальный и вылетал постоянно и тоже что-то с параметрами чудил не понятно. Мой хотя бы не вылетает ;) Формат csv не сильно стандартизированный - слишком много опций нужно учесть чтобы прочесть ВСЕ возможные варианты. |
|||
183
andrewalexk
11.05.21
✎
10:12
|
:)
можно еще проще - без создания избыточных сущностей в сикульной или файловой базе через команду dos findstr /I /g: в текстовый файл |
|||
184
Garykom
гуру
11.05.21
✎
10:23
|
я конечно все понимаю но тут вышло не программирование а какое то шамано-эникейство из разрядо дендрофекальных
причем технологии/инструменты вроде и ничего но применяют их через одно место, вместо нормального программирования |
|||
185
Djelf
11.05.21
✎
10:30
|
(184) А что не так?
Чем отличается подключение расширения к sqlite от подключения расширения к 1С 8.3? И чем отличается подключение внешней таблицы от подключения внешних источников данных к 1С 8.3? Те же яйца, только в профиль... |
|||
186
Garykom
гуру
11.05.21
✎
10:39
|
(185) Не люблю когда на конкретную технологию/софт затачиваются без крайней необходимости не для разовой задачи
Лучше все что можно делать своим кодом, чтобы при необходимости легко с dbf на sqlite или mssql или даже posgtresql перейти |
|||
187
Garykom
гуру
11.05.21
✎
10:43
|
(186)+ В случае ТС раз у него 77 то смотря файловая или sql надо это и юзать
Т.е. отдельно модуль чтения CSV, отдельно загоняние в DBF (тут для файловой можно хак, создать в 1С 7.7 табличку и ее заполнять внешним а искать/читать уже из базы) или в MSSQL (для SQL версии аналогичный хак можно) По сути все встроенное и никаких левых лишних инструментов |
|||
188
Garykom
гуру
11.05.21
✎
10:44
|
(187)+ Справочник в 1С 7.7 создаем под данные, заполняем его снаружи (как таблицу DBF или MSSQL) а юзаем внутри 1С
|
|||
189
Djelf
11.05.21
✎
11:00
|
(186) Ты про sqlite3_mod_csv? Ну, да, увы. Сколько не смотрел реализаций этой виртуальной таблицы для sqlite - все они кривые, а из 1251 вообще не умеют импортировать.
В этом модуле, я заново глянул, параметры разделителя были заявлены, но не реализованы. Можно на Goland слепить аналогично расширение для sqlite - код будет значительно проще, чем на си. (187) Чем хаки лучше ВК к 1С? И... в этом файле же 176 колонок! Он целиком в dbf не помещается! Т.е. нужен не один, а штук 5 справочников... А дебупликация будет довольно затратной. Даже на sqlite дедупликация названий магазинов пару минут занимает, а уж на языке 1С - вечность. Ну а так, да булк-инсерт в mssql и все. Но и тут тот-же самый булк-инсерт, только в sqlite! А механизм расширений к sqlite это не хак, это стандартный и часто используемый механизм sqlite... |
|||
190
evgpinsk_
11.05.21
✎
13:06
|
(184) Можно чуть более конкретней, как именно читать из CSV в dbf или справочник 1с 200МБ текста за пару минут?
Я вроде как и спрашивал про это в (0), т.к. не знал |
|||
191
Djelf
11.05.21
✎
13:08
|
+(189) Специально для любителей Golang. Бинарник и исходники: https://cloud.mail.ru/public/r1Mi/gC37i35yg
А также для сторонников оборачивать все в скрипты...
|
|||
192
evgpinsk_
11.05.21
✎
13:12
|
А Djelf-у отдельный большой респект, даже не столько в помощи по конкретной задаче, сколько в раскрытии самих технологий. Для меня и думаю для многих именно это самое важное.
|
|||
193
Garykom
гуру
11.05.21
✎
13:28
|
(190) файлик делится на несколько в несколько потоков (по числу ядер проца) пишется
|
|||
194
Garykom
гуру
11.05.21
✎
13:30
|
(191) У тебя учетки что ли нет на гитхабе? Заведи, форкни и свои изменения туда
|
|||
195
evgpinsk_
11.05.21
✎
13:35
|
(193) И это не будет "шамано-эникейство" ? ))
Если делать штаными средствами в лоб, то вместо 30 минут потратим 20 ? ) |
|||
196
Garykom
гуру
11.05.21
✎
13:36
|
(195) Это не шаманство в отличие от разных извратов с екселями и прочими а обычное программирование
Фоновые задания даже в 1С есть в 8.3 и многопоточность используют очень часто И не 20 минут а в лучших случаях можно за пару минут |
|||
197
evgpinsk_
11.05.21
✎
13:46
|
(196) В данной теме итоговое решение - не имеет отношения к екселю а использует импорт данных из исходного CSV в 1sqlite.
Напомню что исходный CSV файл - это 230Мб текста, около 700тыс строк и динамические столбцы с ценами магазинов на товары. Просто импорт первых 7ми столбцов в лоб занимает несколько минут, что терпимо, если же также в лоб читать и обрабатывать все остальные 170 столбцов - время критически растёт. И делить файл на части - это и есть костыльное решение проблемы. Всё равно оно будет больше 10минут. Во всей этой теме я увидел конкретный дельный совет, (который смог понять) только от Djelf. Возможно тут были и другие решения, но я как-то их не заметил |
|||
198
Garykom
гуру
11.05.21
✎
13:53
|
(197) просто у кого то "Смотрю в книгу — вижу фигу" ))
а бесплатно за другого (он же зп получает наверно да?) готовый код кодить мне влом, писал только советы как можно |
|||
199
RomanYS
11.05.21
✎
13:55
|
(196) Разве у ТСа ни клюшки? В 8.3 и стандартных средств будет достаточно чтобы быстро прочитать текстовый файл и найти нужную строку
|
|||
200
pechkin
11.05.21
✎
13:56
|
(199) вопрос в скорости
|
|||
201
Garykom
гуру
11.05.21
✎
13:57
|
(199) Да у ТС 77, но это не запрещает юзать параллельную загрузку в несколько потоков
|
|||
202
Garykom
гуру
11.05.21
✎
13:59
|
(201)+ Чисто технически даже если файловая на dbf то зная размер записи и их кол-во легко можно разделить файл на куски, и отдельно их записать в несколько потоков
|
|||
203
RomanYS
11.05.21
✎
14:01
|
(200) ЧтениеТекста и строковые функции в снеговике достаточно быстрые. Я так понимаю задачи распарсить весь файл нет, нужно найти только конкретные ID
|
|||
204
Garykom
гуру
11.05.21
✎
14:02
|
(203) там файл csv 700к строк 260 метров
|
|||
205
RomanYS
11.05.21
✎
14:04
|
(204) гиговых файлах делал тысячи замен подстрок. Затыков в производительности не было
|
|||
206
pechkin
11.05.21
✎
14:04
|
(203) в среднем нужно будет читать половину файла каждый раз. в худшем - весь
|
|||
207
RomanYS
11.05.21
✎
14:07
|
(206) что значит "каждый раз"? Файл же каждый раз новый, естественно не прочитав файл информации не получишь
|
|||
208
Mikeware
11.05.21
✎
14:26
|
(207) он же не "одну позицию" в каждом новом файле ищет...
при каждом поиске - полфайла в среднем. это дофига. |
|||
209
Garykom
гуру
11.05.21
✎
14:29
|
(208) Поэтому надо сделать индекс, куда его засунуть пофиг и читать не весь файл а сразу нужное место его
Для этого для простоты и сразу сделать индекс банально расфигачить один 260 метровый файл на 700к мелких файликов в каждой одна строка а имя файлика это поле для поиска )) |
|||
210
RomanYS
11.05.21
✎
14:30
|
(208) Сколько позиций? Если их не сотни, то можно читать файл и в каждой прочитанной строке искать по списку ИД.
|
|||
211
Mikeware
11.05.21
✎
14:33
|
(209) ну так два пути - 1)читать текстовый файл, делать к нему индекс, и пользоваться. 2)грузить текстовый файл в табличку, индексировать, и пользоваться. (какая уж это табличка - Sqlite, любого SQL, dbf (или сразу в объектном виде)) - уже непринципиально
|
|||
212
Mikeware
11.05.21
✎
14:33
|
(210) сколько строк - столько позиций
|
|||
213
RomanYS
11.05.21
✎
14:33
|
(200) вот тупой замер построчного чтения указанного файла и поиска одной подстроки на средненьком ноуте
Пока Стр <> Неопределено Цикл 680 076 раз 1,944879 сек Стр = Чт.ПрочитатьСтроку(); 680 075 раз 12,735628 сек Поз = СтрНайти(Стр, "012345"); 680 075 раз 4,440355 сек |
|||
214
RomanYS
11.05.21
✎
14:36
|
(212) А! Ему все данные нужны... тогда понятно зачем мутить с промежуточной базой.
Я думал, ему какие-то конкретные ID из всего файла |
|||
215
Garykom
гуру
11.05.21
✎
14:38
|
(214) И у него 7.7
|
|||
216
Mikeware
11.05.21
✎
14:39
|
(214) ну ему прайс приходит, он хочет либо продавать "не дешевле" (или не сильно дороже), или "перекупаться". Эх, прям как в середине 90-х...
|
|||
217
Garykom
гуру
11.05.21
✎
14:39
|
(215)+ Ему уже несколько вариантов предложено
От загрузки в dbf/sql (причем можно и в саму 1С) до разбиения на файлики и поиск это тупо открыть файл с нужным именем |
|||
218
Mikeware
11.05.21
✎
14:39
|
(215) индекс для текстового можно и на клюшках построить.
|
|||
219
Garykom
гуру
11.05.21
✎
14:40
|
(218) Файл такой штатными без внешних не прочитаешь на 77
|
|||
220
Mikeware
11.05.21
✎
14:40
|
(217) а ФС не сдохнет?
|
|||
221
Mikeware
11.05.21
✎
14:41
|
(219) да и насрать. я никогда не был адептом "вах, неодобреные БоГом ВК -низянизянизя"
|
|||
222
RomanYS
11.05.21
✎
14:42
|
(215) Это понятно. Я отчасти поэтому в ветку не заглядывал, казалось что всё это костылестроение из-за невозможности быстро прочитать текстовый файл в клюшках.
|
|||
223
Garykom
гуру
11.05.21
✎
14:43
|
(220) А не похер?
Да и не должна, у меня в папке windows свежеустановленной 209к файлов |
|||
224
Mikeware
11.05.21
✎
14:53
|
(223) ну если только по подпапкам разбивать... такая "ленивая прединдексация"...
|
|||
225
ДенисЧ
11.05.21
✎
14:56
|
(220) (224) Ты что, собрался файлик посимвольно по разным файлам раскидывать?
|
|||
226
Garykom
гуру
11.05.21
✎
15:02
|
(225) есть смысл раскидать по подпапкам с учетом символов индекса
для "нечеткого поиска" |
|||
227
Djelf
11.05.21
✎
15:04
|
Просто оставлю это здесь...
sqlite 35% Faster Than The Filesystem https://www.sqlite.org/fasterthanfs.html |
|||
228
Garykom
гуру
11.05.21
✎
15:06
|
(227) с этим никто не спорит
только in memory еще быстрей и что? а фс на ramdrive ? |
|||
229
Mikeware
11.05.21
✎
15:06
|
(225) не, не посимвольно... имя файла=имени номенклатуры. содержимое файла - строка цен.
т.е. по сути, перекладывание проблем индексации на ФС. |
|||
230
evgpinsk_
11.05.21
✎
15:07
|
Читаю последние сообщения и не догоняю ).
Вот ведь теоретическое нормальное решение (211) , которое в теории было понятно и в (0) Вопрос стоял только в технической реализации. Как технически быстро запихнуть 230Мб текста в dbf или sql. Зачем тут мудрить с разбитием исходного CSV на несколько подфайлов?? Зачем такие заморочки. Когда парсинг через НУЖНЫЙ инструмент занимает до 1й минуты. Нужные инструменты это или существующие готовые скрипты CSVtoDBF - но я находил только платные. Если делать это руками штатными средствами 1с - тогда это десятки минут. Либо предложенный 1sqlite который CSVtoDB3 делает меньше чем за 60 секунд |
|||
231
Garykom
гуру
11.05.21
✎
15:08
|
(229) это я несколько раз и предлагал
|
|||
232
evgpinsk_
11.05.21
✎
15:08
|
(229) Да, либо "имя файла=имени номенклатуры"
|
|||
233
Garykom
гуру
11.05.21
✎
15:09
|
(230) >Если делать это руками штатными средствами 1с - тогда это десятки минут.
просто кто то херовый программист с ограниченным кругозором |
|||
234
Garykom
гуру
11.05.21
✎
15:10
|
(233)+ штатными средствами 1С 7.7 и операционной системы (начиная с winxp) все делается и намного быстрей
|
|||
235
Mikeware
11.05.21
✎
15:11
|
(233) он просто жадный директор
|
|||
236
evgpinsk_
11.05.21
✎
15:20
|
(233) Мне казалось это очевидно. Такие вопросы как в (0) задают крутые программисты??
|
|||
237
Djelf
11.05.21
✎
15:28
|
(236) Да! "Гений 1С" подобные темы создает по 10 раз в день...
|
|||
238
Mikeware
11.05.21
✎
15:30
|
(237) так то ж фикса. он не какой-то "крутой программист", он "гени[т]альный..."
|
|||
239
Garykom
гуру
11.05.21
✎
15:36
|
(238) это я тоже фикса и что? ну это кроме фри
он просто засиделся на одном месте и почти утонул в болоте |
|||
240
Mikeware
11.05.21
✎
15:54
|
(239) ты фикса с Фиксиным не путай
|
|||
241
andrewalexk
12.05.21
✎
20:26
|
||||
242
Mikeware
13.05.21
✎
12:00
|
(241) раньше они были
https://upload.wikimedia.org/wikipedia/ru/1/15/Гарантийные_человечки_обложка_1975.jpg |
|||
243
Кирпич
13.05.21
✎
12:30
|
А я, кстати, настрочил утилитку csv2dbf. Cоздает dbf из csv. Может делить csv вдоль и поперек(вынимать отдельные столбцы и делить на несколько dbf файлов). Работает шустро. Файл автора (700 тыс строк и 175 столбцов) обрабатывает за 5 секунд.
Usage: C:\temp\csv2dbf\csv2dbf.exe [<options>] <input csv file name> [<out dbf file name>] Options: -h --help show help -b --showtime - show execution time -d --delimiter -column delimiter ("," or ";" or "tab" default ";") -p --skipfirst - skip first line in csv -t --dbfcount=<number> - split all records to <number> dbf files -c --cols=<number,number,...> - take columns only from the list <number,number,...> -n --colnames=<string,string,...> - list of columns for dbf (number of column names must match cols parameter) Examples: 1) csv2dbf --skip=true --split=3 --cols=3,4,8 --colnames=ID,NAME,PRICE c:\temp\price.csv c:\temp\price.dbf 2) csv2dbf -s true -p 3 -c 3,4,8 -n ID,NAME,PRICE c:\temp\price.csv c:\temp\price.dbf 3) csv2dbf --cols=1,2,3,8,9 c:\temp\price.csv c:\temp\price.dbf 4) csv2dbf c:\temp\price.csv |
|||
244
Garykom
гуру
13.05.21
✎
13:13
|
(243) Допили утилитку чтобы .DD или .DDS читал и данные засовывал в нужные/указанные sc* и продай ТС
|
|||
245
Garykom
гуру
13.05.21
✎
13:14
|
(244)+ только вместо кучи параметров один файл настроек чтобы
|
|||
246
Mikeware
13.05.21
✎
13:21
|
(245) и вместо файла - гуй
|
|||
247
Кирпич
13.05.21
✎
13:29
|
(244) "в нужные/указанные sc*" Это не нужно и сложно(индексы и всё такое). Да автор свою проблему уже решил.
(245) Да в bat файл написать все параметры и хватит |
|||
248
Garykom
гуру
13.05.21
✎
13:36
|
(247) Так и индекс создавай заодно
|
|||
249
Злопчинский
13.05.21
✎
13:37
|
(243) глумишься? ссылка на скачивание - где? ;-)
|
|||
250
Кирпич
13.05.21
✎
13:41
|
(249) Ссылки еще нету. Завтра красоту наведу и покажу. Сегодня у меня покос травы.
|
|||
251
Злопчинский
13.05.21
✎
13:46
|
Покос Травы, Газон Засеян - армяне что ли в гости приезжают?
|
|||
252
Кирпич
13.05.21
✎
14:33
|
(251) Тёща
|
|||
253
Кирпич
13.05.21
✎
18:42
|
(249) От она https://dropmefiles.com/qNnNg
Usage: csv2dbf.exe [<options>] <input csv file name> [<out dbf file name>] Options: -h --help show help -b --showtime - show execution time -d --delimiter - column delimiter ("," or ";" or "tab" default ";") -p --skipfirst - skip first line in csv -t --dbfcount=<number> - split all records to <number> dbf files -c --cols=<number,number,...> - take columns only from list <number,number,...> -n --colnames=<string,string,...> - list of columns for dbf (number of column names must match cols parameter) Examples: 1) csv2dbf --skipfirst --dbfcount=3 --cols=3,4,8 --colnames=ID,NAME,PRICE c:\temp\price.csv c:\temp\price.dbf 2) csv2dbf -p 3 -c 3,4,8 -n ID,NAME,PRICE c:\temp\price.csv c:\temp\price.dbf 3) csv2dbf --cols=1,2,3,8,9 c:\temp\price.csv c:\temp\price.dbf 4) csv2dbf c:\temp\price.csv |
|||
254
Злопчинский
13.05.21
✎
18:48
|
(253) взял, нехай будет
|
|||
255
Garykom
гуру
13.05.21
✎
18:56
|
(253) кинь на гитхаб исходники допилю
и у тебя корректно разбирает если разделитель внутри строковых полей? |
|||
256
Кирпич
13.05.21
✎
19:10
|
(255) попробуй. Я сильно не тестировал
|
|||
257
Кирпич
13.05.21
✎
19:20
|
Такое должна разбирать
"Раз два ;три";"раз ""два"" три" |
|||
258
Кирпич
13.05.21
✎
20:08
|
Один косяк нашел.
Вот такое не корректно разбирает Раз "два" три;раз два три |
|||
259
Кирпич
13.05.21
✎
20:10
|
исправил https://dropmefiles.com/DXhJp
|
|||
260
Djelf
14.05.21
✎
11:07
|
(259) Нереально быстро пережевывает!
Я так понимаю csv весь в память сначала забирается, т.е. ограничение на объем есть? |
|||
261
Кирпич
14.05.21
✎
11:56
|
(260) ага. потом доработаю
|
|||
262
Кирпич
14.05.21
✎
11:57
|
но вряд ли у кого гиговые csv бывают
|
|||
263
Кирпич
14.05.21
✎
12:08
|
ну и тупо 64 битный exe сделать можно
|
|||
264
Кирпич
14.05.21
✎
12:31
|
Добавил x64 и с ковычками подшаманил. Теперь разбирает такую пургу
"one" two;"one two";one "two";100 "on""e""" two;"one two";one "tw""zzz""o";"200" "on""e""" two;"one two";one "tw""zzz""o";Иванов "200" "on""e""" two;"one two";one "tw""zzz""o";"Иванов" "200" https://dropmefiles.com/okW1r На счет памяти. Я использую memory-mapped https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files. Но я тупо весь файл маплю. Не охота было заморачиваться кусками. |
|||
265
Кирпич
14.05.21
✎
12:33
|
||||
266
Garykom
гуру
14.05.21
✎
12:45
|
(258) >Раз "два" три;раз два три
эээ по правилам валидного CSV должно быть "Раз ""два"" три";раз два три |
|||
267
Кирпич
14.05.21
✎
12:53
|
(266) так оно вроде и то и то съест
|
|||
268
Djelf
14.05.21
✎
13:45
|
(265) Работает. И х32 и х64. Но создает dbf больше 2х гигов, понятно что это обходится с помощью --dbfcount, но может стоит автоматом, после достижения 2х гигов разбивать?
|
|||
269
Djelf
14.05.21
✎
13:55
|
+(268) Или даже лучше ключ --split=len
|
|||
270
pechkin
14.05.21
✎
14:09
|
а что на гитхабе не выложишь?
|
|||
271
Кирпич
14.05.21
✎
14:19
|
Ну может потом сделаю автоматом. Просто думаю, что лучше фиксированное количество файлов. Потом просто знаешь количество файлов и не надо вычислять в 1с сколько их там нагенерило.
|
|||
272
Кирпич
14.05.21
✎
14:20
|
(270) выложу. Потестирую немножко.
|
|||
273
Djelf
14.05.21
✎
15:17
|
(271) Разбивка на фиксированное количество кусков имеет право на жизнь.
Но вот например так: нужно потом добавить пару колонок, и можно примерно вычислить какой изначальный объем потребуется, чтобы перебора не было. А точно количество файлов не так существенно, это перебором в каталоге легко вычисляется... Вот дедупликацию бы прикрутить! О... это было бы мегакруто! |
|||
274
Кирпич
14.05.21
✎
15:39
|
чо такое дедупликация
|
|||
275
Кирпич
14.05.21
✎
15:39
|
?
|
|||
276
Кирпич
14.05.21
✎
15:42
|
"Но вот например так: нужно потом добавить пару колонок, и можно примерно вычислить какой изначальный объем потребуется, чтобы перебора не было. "
это вабще не понял |
|||
277
Злопчинский
14.05.21
✎
15:51
|
(274) https://ru.wikipedia.org/wiki/Дедупликация
- видимо Djelf имел в виду приапменение на этапе чтения исходных данных... тогда можно впихнуть в память бОльший массив |
|||
278
Djelf
14.05.21
✎
15:57
|
(274) дедупликация? Выкидывание группы полей в отдельную таблицу с заменой ссылок на ключевое поле в исходной таблице.
Я попробовал нарисовать для таблицы которую прислал (0) на триггерах sqlite, не так плохо получилось ~2-3 минуты (переменных в sqlite нет, это иногда выбешивает). (276) см. пост (162) для (0) потребуется отдельная колонка для индекса и ее придется добавить и файл может стать слишком большим! |
|||
279
Djelf
14.05.21
✎
16:22
|
+(278) ИМХО ключ примерно такой "--dedup=code43,code44:code.dbd:into:code43"
|
|||
280
Кирпич
14.05.21
✎
16:47
|
(278) Ну выгрузи какие надо столбцы в одну таблицу, другие столбцы в другую. Запусти просто несколько раз с разными параметрами. Одновременно запустишь пару-тройку csv2dbf, будет то же время :)
|
|||
281
Кирпич
14.05.21
✎
16:48
|
(280) Типа
-c 1,2,3,4,5 test.csv test1.dbf -c 1,6,7,6,9 test.csv test2.dbf |
|||
282
Djelf
14.05.21
✎
16:52
|
(281) А ссылку то как получить на поле из новой/дополнительной таблицы в оригинальную?
|
|||
283
D3O
14.05.21
✎
16:54
|
(0) вдруг никто еще не предлагал - пробовать затягивать в sqlite - под 7.7 он в отличнейшей обертке есть от Орефкова, кажется. скорее всего сам sqlite имеет механизм подключения к csv. а уж дальше с его помощью все должно получиться крайне быстро.
|
|||
284
Кирпич
14.05.21
✎
16:54
|
(282) Ну у тебя же есть ключевое поле. Копируй его во все таблицы
|
|||
285
Кирпич
14.05.21
✎
16:59
|
Для (0) можно просто обойтись разделением на несколько dbf и потом, для поиска, искать во всех dbf по очереди.
|
|||
286
Кирпич
14.05.21
✎
17:01
|
(283) уже так и сделали
|
|||
287
Djelf
14.05.21
✎
17:02
|
(284) Посмотри что у меня получается: https://cloud.mail.ru/public/HUSG/y6xkTfR9S
Так быстрее будет... |
|||
288
Кирпич
14.05.21
✎
17:06
|
(287) Куда еще быстрее? 5 сек и получаем 4 dbf. 5 секунд на индексирование ключевого столбца в dbf. 10 секунд в день - вполне приемлемо. У нас же не олимпиада по быстрой загрузке csv
|
|||
289
Djelf
14.05.21
✎
17:09
|
(288) Я не про время импорта написал, а про дудупликацию (про структуру импортируемых таблиц).
А если бы была Олимпиада, то ты, без вариантов, победитель. Скорость, импорта, повторяю, невероятная! |
|||
290
Кирпич
14.05.21
✎
17:15
|
(289) у меня на этом компе не чем смотреть sqlite базы
ну вот же ддедупликация. Не? -c 1,2,3,4,5 test.csv test1.dbf -c 1,6,7,8,9 test.csv test2.dbf ключ в столбце 1 |
|||
291
Кирпич
14.05.21
✎
17:23
|
Надо в sqlite попробывать еще. Может тоже секунд за 10 всосёт
|
|||
292
Кирпич
14.05.21
✎
17:23
|
пардон за попробывать
|
|||
293
Djelf
14.05.21
✎
17:26
|
(290) Не! Я же не смогу подменить поле на ключ при загрузке!
Эта штука бесплатная: http://www.sqliteexpert.com/download.html Магазины. Их всего 174, их пишем в отдельную табличку, но их в csv очень много дублируется. Просто +экономия места и +поиск по ключу. |
|||
294
Кирпич
14.05.21
✎
17:37
|
(293) А. Дошло. Столбцы в строки переделать.
|
|||
295
Djelf
14.05.21
✎
17:47
|
(294) Это был следующий (второй) этап дедупликации, на первом было бы достаточно свернуть Раздел,Производитель и т.п.
Магазины же в кросс-таблице, это без дополнительного скрипта сложно сделать. Можно, но не универсально. Для sqlite свертка магазинов как то так выглядит:
|
|||
296
Кирпич
14.05.21
✎
17:50
|
(295) Ну это пусть автор извращется. Далеко не у каждого такие проблемы.
|
|||
297
Garykom
гуру
14.05.21
✎
17:50
|
Вы только до http сервиса удобного с автоматическим обновлением там прайса и готовыми модулями для разных 1С не доберитесь случайно
|
|||
298
Кирпич
14.05.21
✎
17:53
|
(287) Нифига ты ему забабахал. Нахаляву чтоли?
|
|||
299
Djelf
14.05.21
✎
17:54
|
(296) Я просто обновлял в своей памяти работу с триггерами! Забывается же все постепенно...
(297) А в чем проблема прикрутить сервис на Golang? БД есть, как быстро заполнить уже понятно. Минут 10-15 работы ;) |
|||
300
Garykom
гуру
14.05.21
✎
17:56
|
(299) бесплатно? только если как пет-проекта для портфолио на гитхабе
|
|||
301
Кирпич
14.05.21
✎
18:01
|
Если извращаться со всякими дедупликациями, то для этого питон есть. Надо попробовать чо получится по времени.
|
|||
302
Djelf
14.05.21
✎
18:02
|
(300) Это же только для себя, любимого забесплатно! Тут нужно недели две на согласование API и ABI... А это совсем не бесплатно ;)
|
|||
303
Кирпич
14.05.21
✎
18:09
|
Гы. Сколько параметров должно быть у csv2dbf
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html |
|||
304
Garykom
гуру
14.05.21
✎
18:20
|
(303) поэтому и сразу написал выноси в файл настроек операции и только один параметр у csv2dbf - имя файла настроек
|
|||
305
Djelf
14.05.21
✎
18:23
|
(303) Мне кажется и этого не хватит, на все креативные файлы....
|
|||
306
evgpinsk_
16.05.21
✎
13:33
|
(287) Уж ты, упустил ветку. Да, очень не плохие вещи )
Больше для себя, что бы не пропало: https://drive.google.com/drive/folders/1fndNmavzk9KQJ9DUcQPOzdgQXwa02Mcm?usp=sharing красивая БД: https://prnt.sc/12zs75d |
|||
307
evgpinsk_
16.05.21
✎
13:45
|
(265) Тоже круто - exe для чтения CSV в DBF
И этот способ попроще для многих чем 1sqlite использовать ) |
|||
308
ДедМорроз
16.05.21
✎
17:42
|
База sqlite сама по себе не быстрая,т.к.в отличие от dbf имеет страничную структуру.
Лучше сунуть нос в сторону ms sql express и в нем bulk insert. |
|||
309
Кирпич
16.05.21
✎
18:05
|
(308) Глупости говорите. Sqlite Побыстрее ms sql express будет. А страничная структура к быстродействию вообще не имеет никакого отношения. Sqlite не предназначена для многопользовательской работы и клиент-сервера. Если её использовать только для чтения (как и нужно автору), то она быстрая как чёрт.
|
|||
310
ДедМорроз
16.05.21
✎
23:12
|
Журнал регистрации 1с в некоторых версиях на sqlite,и что-то быстроты там не видно.
|
|||
311
trdm
17.05.21
✎
06:50
|
(308) да, она временами не быстрая. Транзакцию надо использовать.
|
|||
312
trdm
17.05.21
✎
06:53
|
(0) > Необходим быстрый поиск информации в больших CSV файлах
Надо напомнить, то csv файлы - текстовые, и доступ там последовательный. Т.е. что-бы что-то найти надо пробежать практически весь файл. Тогда как реляционки с индексами - имеют произвольный сопоб доступа. |
|||
313
Кирпич
17.05.21
✎
07:59
|
(310) ну вот как раз пример как не надо использовать sqlite
|
|||
314
Garykom
гуру
17.05.21
✎
08:00
|
(312) Хочу напомнить что зависит от размера csv файла
На размере как у ТС можно весь закинуть в память и даже полным сканированием достаточно быстро "в пределах нескольких секунд" находить |
|||
315
Garykom
гуру
17.05.21
✎
08:01
|
(314)+ В смысле сейчас когда объем памяти даже офисных машинок от 8 гигов это норма
Раньше согласен приходилось извращаться с какими то базами и индексами, сейчас можно решать задачу тупо в лоб |
|||
316
evgpinsk_
17.05.21
✎
08:57
|
(314) Вот как-раз следующий вопрос частично касается этого.
Я замарочился (пришлось вспоминать синтаксис SQL) и привёл db3 базу исходного CSV файла к нормализованному виду: вместо одной таблицы, в которой цены магазинов в столбцах одной тоблицы, использую 5 табличек. https://prnt.sc/130xbq3 Таблица Прайс имеет вид: идТовара (создан индекс по полю) идМагазина Цена Но не пойму механизм использования индекса. Почемуто этот запрос: ТекстЗапроса="SELECT Магазины.Наименование, Прайс.Цена, Прайс.СрокДоставки |FROM (Прайс INNER JOIN Товары ON Прайс.Товар = Товары.Код) INNER JOIN Магазины ON Прайс.Магазин = Магазины.Код |WHERE (((Товары.СуперКлюч)='"+СокрЛП(ТМЦ.МодельНаОнлайнере)+"'))"; не использует индекс, т.к. время его отработки у меня составляет 370 милиСек что в 20 раз больше чем обычный запрос Select к ненормализованной исходной таблице price.db3 - около 15 милиСек Вопрос : что я сделал не так? |
|||
317
evgpinsk_
17.05.21
✎
09:05
|
(314) В моём случаем поиск "несколько секунд" - это многовато. Пользователь находится в счёте, и нажимает кнопку на товарах, чтобы быстро посмотреть цены конкурентов.
Здесь отклик желателен в милисекунды |
|||
318
Ёпрст
17.05.21
✎
09:16
|
(316) код, канечна адок.
Хотя бы where перенеси в join, для начала |
|||
319
Djelf
17.05.21
✎
09:21
|
(316) Для начала запусти analyze, затем, если не сработает explain query plan select...
Ну и лучше не использовать inner join, а использовать left join, т.е. сначала отобрать Товары по ключу, а потом уже к таблице товары клеить Прайс. |
|||
320
evgpinsk_
17.05.21
✎
09:27
|
(318) Не силён в составлении sql запросов. Понимаю, но с нуля сложновато их писать. Беру код, который строит msAccess, и он именно так написал код
Графическое представление https://prnt.sc/130yoc1 я не вижу здесь ошибки, запрос построен помоему верно. и вот текстом этот же запрос: SELECT Прайс.Товар, Прайс.Магазин, Прайс.Цена FROM (Прайс INNER JOIN Магазины ON Прайс.Магазин = Магазины.Код) INNER JOIN Товары ON Прайс.Товар = Товары.Код WHERE (((Товары.КодОнлайнера)="Экземпляр")); |
|||
321
Garykom
гуру
17.05.21
✎
09:30
|
(316) Нафик нормализовывать если это не требуется?
|
|||
322
evgpinsk_
17.05.21
✎
09:32
|
(321) Согласен, просто нравится когда красиво, да и не забыл ещё немного уроки института )
Тут вопрос больше теоретический, каким образом работаем механизм использования индексов СУБД "SQLiteBase" В простейшем случае когда выборка из одной таблицы - он используется. Но когда в запросе несколько таблиц, почемуто нет. Ведь явно его както в коде 1с не нужно задавать? Если ответ с ходу не виден - тогда можно забить |
|||
323
acanta
17.05.21
✎
09:35
|
А индекс может отвалиться из за вот этих вот сокрлп() и т.п.?
|
|||
324
evgpinsk_
17.05.21
✎
09:37
|
(323) Разве сокрЛП() имеет отношение к индексу?. Функция просто в текст запроса передаёт верно параметр
|
|||
325
evgpinsk_
17.05.21
✎
09:39
|
(319) Поменял на left join, стало быстрее,
ТекстЗапроса="SELECT Магазины.Наименование, Прайс.Цена, Прайс.СрокДоставки |FROM (Прайс LEFT JOIN Товары ON Прайс.Товар = Товары.Код) LEFT JOIN Магазины ON Прайс.Магазин = Магазины.Код |WHERE (((Товары.СуперКлюч)='"+СокрЛП(ТМЦ.МодельНаОнлайнере)+"'))"; но индексы всё равно не используются. Сейчас Результат возвращается за 2800 милиСЕк Напомню что из ненормализоваенной таблицы по ключу Товары.СуперКлюч результат возвращается за 28 милисекунд |
|||
326
Djelf
17.05.21
✎
09:46
|
(325) Что по твоему делает этот код? FROM (Прайс LEFT JOIN Товары ON Прайс.Товар = Товары.Код)
Он перебирает весь прайс и ко всему прайсу клеит товары. И только потом ставит фильтр на Товары.СуперКлюч Наоборот пиши: FROM Товары LEFT JOIN Прайс ON Прайс.Товар = Товары.Код |
|||
327
evgpinsk_
17.05.21
✎
09:48
|
А не может быть медленный поиск связан с тем что в нормализованной таблице 'прайсы' строк в пять раз больше чем в не нормализованной? Маловероятно но всё же.
|
|||
328
evgpinsk_
17.05.21
✎
09:48
|
(326) понял через час приеду и попробую исправить
|
|||
329
Кирпич
17.05.21
✎
10:01
|
(327) Конечно может. Особенно если индексов нет.
|
|||
330
Djelf
17.05.21
✎
10:14
|
Да есть у него индекс по товару. Это оптимизатор sqlite дурит...
Что-то я помню такого странного поведения. Решается плюсом перед Товары.Код. FROM Товары LEFT JOIN Прайс ON Прайс.Товар=+Товары.Код |
|||
331
trdm
17.05.21
✎
10:32
|
(321) > Нафик нормализовывать если это не требуется?
Бест практих под хайлоад |
|||
332
Garykom
гуру
17.05.21
✎
10:40
|
(331) хайлоад это отказ от sql, использование in-memory database и баз типа ключ-значение
причем делают всевозможные значения на которые навешивают нужное явно отказываясь от нормализации в угоду скорости ответа |
|||
333
Garykom
гуру
17.05.21
✎
10:42
|
(332)+ в случае 1С 7.7 это написание ВК, которая грузит CSV в оперативку и затем мгновенно отвечает
|
|||
334
trdm
17.05.21
✎
11:05
|
(332) нет, это набор правил для разруливания высоких нагрузок.
Отказ от скуля тут не принципиален. |
|||
335
trdm
17.05.21
✎
11:06
|
+ ты же в курсе, что скуль сам загоняет наиболее юзабельные части данных в оперативку?
|
|||
336
Кирпич
17.05.21
✎
11:14
|
(333) Для этого и ВК не надо. Есть же WSH. Да и грузить всё в память несчастной семерки это жестоко.
|
|||
337
evgpinsk_
17.05.21
✎
12:42
|
(326) (330)
Мне предполагается что действительно "дурит оптимизатор sqlite SQL кода " перенёс в MSAccess эти таблицы (прайс 2,1млн строк, товары 700тыс строк) и этот же запрос в нём отрабатывается мгновенно, десятые доли секунды SELECT Товары1.СуперКлюч, Магазины1.Наименование AS Магаз, Товары1.Наименование AS Товар, Прайс1.Цена, Прайс1.СрокДоставки FROM (Прайс1 INNER JOIN Товары1 ON Прайс1.Товар = Товары1.Код) INNER JOIN Магазины1 ON Прайс1.Магазин = Магазины1.Код WHERE (((Товары1.СуперКлюч)="usb08087805")); он же в графической форме: https://prnt.sc/1315k2x |
|||
338
evgpinsk_
17.05.21
✎
13:06
|
(318) > Хотя бы where перенеси в join, для начала
ТекстЗапроса="SELECT Магазины.Наименование, Прайс.Цена, Прайс.СрокДоставки |FROM (Прайс INNER JOIN Товары ON Прайс.Товар = Товары.Код) INNER JOIN Магазины ON Прайс.Магазин = Магазины.Код |WHERE (((Товары.СуперКлюч)='"+СокрЛП(ТМЦ.МодельНаОнлайнере)+"'))"; было бы интересно попробовать, но не знаю как ) нужно решать через Запрос в Запросе? |
|||
339
Djelf
17.05.21
✎
13:07
|
(337) Еще раз повторяю - поставь + перед Товары1.Код
Т.е. на так ON Прайс1.Товар = Товары1.Код, а вот так ON Прайс1.Товар = +Товары1.Код |
|||
340
Ёпрст
17.05.21
✎
13:11
|
(338) че как ? выкинь where и в своём inner join воткни and Товары.СуперКлюч =
|
|||
341
Ёпрст
17.05.21
✎
13:15
|
или так, хотя бы:
|SELECT Магазины.Наименование, Прайс.Цена, Прайс.СрокДоставки |from Товары |left join Прайс on Прайс.Товар = Товары.Код |left join Магазины on Прайс.Магазин = Магазины.Код |WHERE Товары.СуперКлюч ='"+СокрЛП(ТМЦ.МодельНаОнлайнере)+"'"; |
|||
342
evgpinsk_
17.05.21
✎
13:54
|
(339) Забыл отписать, плюсики не меняют ситуацию, индекс не задействуется
(340) (341) сейчас попробую |
|||
343
evgpinsk_
17.05.21
✎
14:16
|
(341) Это помогло, вместо 2000 мсек стало 300мсек
не уверен что это правильный результат, т.к. напомню в не оптимизированном сплошном прайсе из одной таблицы поиск длится 15 милисек |
|||
344
evgpinsk_
17.05.21
✎
14:21
|
п.с. Сейчас заметил свою ошибку, я в таблице Прайс забыл сделать индекс по полю Магазин
а оно используется в join Хотя странно, добавление индекса по полю Магазин не повлияло на скорость - сейчас теже 300 милисек Итого имеем , что поиск в базе из 3х оптимизированных таблиц в 20 раз медленнее (0,3сек) чем в одной сплошной таблице (0,015сек). п.с.с. Вопрос имеет чисто теоретический интерес, на него можно смело забить ) |
|||
345
Djelf
17.05.21
✎
14:45
|
(342) Та какую версию 1sqlite то используешь? Небось какую-то древнюю? Возьми мою сборку посвежее https://cloud.mail.ru/public/9znr/ZJ6ULE9aR
В старых версиях довольно плохой планировщик, он очень плохо переваривает inner join. Более новая должна давать результат примерно соответствующий (343). Вот теперь плисик туда добавь и станет 1-2 микросекунды. Но ты же посмотрел explain query plan select... как я советовал. У тебя план запроса примерно такой id parent notused detail 3 0 0 SEARCH TABLE Товары USING INTEGER PRIMARY KEY (rowid=?) 6 0 0 SCAN TABLE Прайс Индекс по товару в Прайсе не используется. А не используется потому что во-первых это не очень хороший индекс (много дублей), а во вторых без плюсика, который подавляет использование ключевого индекса в Товарах sqlite дуркует. Но можно не только плюсиком заставить sqlite использовать этот индекс, вот так вот должно работать, см. план ниже LEFT JOIN Прайс INDEXED BY Товар ON Прайс.Товар = Товары.Код id parent notused detail 4 0 0 SEARCH TABLE Товары USING INTEGER PRIMARY KEY (rowid=?) 7 0 0 SCAN TABLE Прайс USING INDEX Товар |
|||
346
Djelf
17.05.21
✎
14:49
|
(344) При запросе используется только один индекс! Индекс по Магазину никак не мог изменить скорость выборки.
Ну и чему ты в (344) удивляешься? Ясное дело, что запрос к плоской таблице по уникальному индексу будет быстрее. |
|||
347
pechkin
17.05.21
✎
14:56
|
(346) 2 разных индекса никак не могут использоваться для поиска записи
|
|||
348
evgpinsk_
17.05.21
✎
14:57
|
(345) Чудеса бывают, плюсик помог на свежей версии 1sqlite )
ТекстЗапроса="SELECT Магазины.Наименование, Прайс.Цена, Прайс.СрокДоставки |FROM Товары |LEFT JOIN Прайс ON Прайс.Товар = +Товары.Код |LEFT JOIN Магазины ON Прайс.Магазин = +Магазины.Код |WHERE Товары.СуперКлюч ='"+СокрЛП(ТМЦ.МодельНаОнлайнере)+"'"; поиск стал вместо 300 мСек 30 мСек а когда добавил индекс и на Магазин то 8 мСек :) |
|||
349
evgpinsk_
17.05.21
✎
15:01
|
(347) Верно. просто значит первая попытка без кеша (поэтому более медленная)
Добавление индекса по полю Магазин - не увеличивает скорость сейчас она стала 8мСек помогла свежая версия 1sqLite и плюсики в тексте запроса |
|||
350
Djelf
17.05.21
✎
15:07
|
(349) Базу то скинь, с которой работаешь. 30мс в (348) ИМХО слишком долго! Должно быть 0-1мс.
|
|||
351
evgpinsk_
17.05.21
✎
15:10
|
Ну и самый прикол что поиск длиться теже 8 мСек в моём первоначальном запросе из (316) :)
ТекстЗапроса="SELECT Магазины.Наименование, Прайс.Цена, Прайс.СрокДоставки |FROM (Прайс INNER JOIN Товары ON Прайс.Товар = Товары.Код) INNER JOIN Магазины ON Прайс.Магазин = Магазины.Код |WHERE (((Товары.СуперКлюч)='"+СокрЛП(ТМЦ.МодельНаОнлайнере)+"'))"; |
|||
352
evgpinsk_
17.05.21
✎
15:12
|
(350) Сейчас результат на любых вариантах Select - 8мСек
30мСек в (348) - был глюк первого запуска. Заметил что иногда первый запускает тормозит. Потом все пыпытки стабильно 7-9 мСек |
|||
353
evgpinsk_
17.05.21
✎
15:16
|
https://dropmefiles.com/ec9WK
оптимизированная база. в ней же таблица Price - исходная не нормализированная |
|||
354
Djelf
17.05.21
✎
15:18
|
(351) Это не прикол, в версиях Орефкова движок sqlite 3.7.11, а начиная с движка 3.8.0 поменялся оптимизатор: https://runebook.dev/ru/docs/sqlite/queryplanner-ng
С 1С 7.7 он работал криво, насколько помню в 3.14.0 починили работу нового планировщика с виртуальными таблицами (которыми являются таблицы 1С 7.7). |
|||
355
evgpinsk_
17.05.21
✎
15:19
|
(346) > Ну и чему ты в (344) удивляешься? Ясное дело, что запрос к плоской таблице по уникальному индексу будет быстрее.
Не знал, тогда действительно в моём частном случае правильней и проще держать плоскую базу. Найти нужную строку по коду товара, и в ней уже выбрать цены магазинов из столбцов |
|||
356
Djelf
17.05.21
✎
15:31
|
(355) Тут не понятно что будет быстрее.
Ты же можешь с нормализованной таблицей получать цены в разрезе магазин, а с плоской нет. Если тупо "товар" -> "строка прайса" -> "список магазинов с ценами", возможно плоская будет быстрее, даже при учете того что разбирать колонки придется в 1С. |
|||
357
Злопчинский
17.05.21
✎
15:38
|
исходить надо из перспектив среднесрочных. если создаваемый инструмент важен - то следует делать сразу правильно, это в будущем окупится.
|
|||
358
evgpinsk_
17.05.21
✎
15:45
|
(356) > Ты же можешь с нормализованной таблицей получать цены в разрезе магазин, а с плоской нет.
с плоской нет - средствами SQL но ведь элементарно получив строку из базы, потом ручками вытянуть цены магазина по названию колонк (они формализованы: Магазин1, Магазин2) (357) согласен, но в моём случае врядли будет усложнение именно этой задачи в будущем (хотя кто его знает). п.с. Вынашиваю очень долго не простую задачу по импорту прайсов поставщиков в базу 1с. Есть не совсем простые вопросы по теоретической части. /уже както подымал тему ранее/ Соберусь с мыслями и попробую поднять новую тему ещё раз ) |
|||
359
Djelf
17.05.21
✎
15:53
|
(358) А ты попробуй, без нормализации, вытянуть цены по одному из магазинов.
Но есть же не только магазины, но и срок доставки! Вот тебе еще и один повод для нормализации базы. |
|||
360
evgpinsk_
17.05.21
✎
16:10
|
(359) Да, по магазину очень не просто. В моём частном случае эта задача не стоит. Нужен просто анализ рынка для конкретному товару
|
|||
361
evgpinsk_
17.05.21
✎
16:33
|
(359) срок доставки - не мешает использовать плоскую таблицу. Это ведь такой же параметр как и цена
|
|||
362
Djelf
17.05.21
✎
16:38
|
(361) Ты де уже добился приемлемой скорости? Даже 300мс это ерунда, стало 30мс, это уже более чем приемлемо. Забудь (на время).
|
|||
363
evgpinsk_
17.05.21
✎
18:16
|
(362) Да, всё ок. Уже 8 милисекунд. Для этой задачи это с большим запасом
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |