Имя: Пароль:
1C
1C 7.7
v7: Необходим быстрый поиск информации в больших CSV файлах
, ,
0 evgpinsk_
 
01.05.21
13:07
Есть прайс в формате CSV площадки onliner.by
В нём 700 тыс позиций.
Раз в сутки прайс обновляется.

Стоит задача в 1с получать быстрый доступ к цене определённого товара из данного прайса (скорость желательна в пределах нескольких секунд).
В прайсе есть столбец "IDтовара" по которому будет осуществляться поиск.

Вопрос: Каким образом осуществлять поиск, через какие инструменты?
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 свертка магазинов как то так выглядит:

        ЗапросТриггераПрайс = "";
        Для НомерМагазина=1 По КоличествоМагазинов Цикл
            ЗапросТриггераПрайс = ЗапросТриггераПрайс+"
            |INSERT OR IGNORE INTO Прайс(
            |    Магазин,
            |    Товар,
            |    Цена,
            |    СрокДоставки
            |) VALUES (
            |    (SELECT Код FROM Магазины WHERE new.[Магазин "+НомерМагазина+"] IS NOT NULL AND Наименование = new.[Магазин "+НомерМагазина+"] LIMIT 1),
            |    (SELECT Код FROM Товары WHERE new.[Магазин "+НомерМагазина+"] IS NOT NULL AND Код = new.[ID товара] LIMIT 1),
            |    new.[Цена "+НомерМагазина+"],
            |    new.[Срок доставки "+НомерМагазина+"]
            |);"
        КонецЦикла;
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 милисекунд. Для этой задачи это с большим запасом
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший