powered by simpleCommunicator - 2.0.35     © 2025 Programmizd 02
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
25 сообщений из 39, страница 1 из 2
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39480918
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предыстория вопроса:
Есть сайт, у него в базе данных хранятся товары, меня интересуют 2 таблицы: таблица товаров(название и т.д.) и характеристики товаров("id записи", "id атрибута", "Значение атрибута"). Т.е. все товары в 1 таблице, характеристики во 2.
Для моей программы я выбрал "SQLite3", для хранения данных в файле "База Данных", т.к. записей очень много, то и поэтому от "Хранения в памяти" я отказался.
Делаю я файл "SQLite3"(php скрипт на сервере. Также 2 таблицы, т.е. скопировал структуру таблиц), скачиваю, смотрю товары в разделе, радуюсь. Но вот вздумалось мне прикрутить фильтр. Потираю руки, делаю:
>>>>
Получаю список всех товаров(по количеству).
Делю его на количество процессоров, чтобы максимизировать скорость.
Цикл:
1. Результат запроса(из 1-й таблицы, конкретный товар)
2. По его id я делаю запрос в этом же соединении на "список атрибутов"
3. Записываю в массив на вывод
>>>>
Тестовое количество товаров - ~326 000
Атрибуты: у кого-то 4, у кого-то 0.
Язык реализации: C#

Проблема: если с пунктом #2 - вывод на 6-ядерном компе - 2 минуты 30 секунд, если комментирую пункт "номер 2" - 3.5 секунды. Собственно вопрос: как выкрутится? т.к. планируется выводить 1-1.5-2 миллиона товаров. Я жду любые советы. Желательно с примерами.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39480919
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911Язык реализации: C#
Это для справки. Мне нужно узнать логику решения, поэтому обратился на форум, посвящённый базе данных.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39480920
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Идея: хранить "список атрибутов" по "id товара" в памяти не считаю хорошей, т.к. при 20 миллиона товаров в баззе данных, при наличии 5-7(для простоты, рассмотрим самый тяжёлый случай - 10 атрибутов) - память, программа, будет сжирать охотно.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39480926
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911характеристики товаров("id записи", "id атрибута", "Значение атрибута")
я ошибся с написанием. Вот так правильно: характеристики товаров("id записи", "id товара", "id атрибута", "Значение атрибута")
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39480944
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911,

Как бы нет точного определения таблицы, типов, индексов, каким именно запросом выполняет #2, плана запроса... ну и собственно ничего сказать толком не получится
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39481074
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот рассматриваемый кусок:

CREATE TABLE `TOBAPbl_ATTPu6yTbl`(
`id` INTEGER PRIMARY KEY,
`id_TOBAPA` TEXT,
`id_ATPu6yTA` TEXT,
`ZHA4eHue` TEXT
);
CREATE TABLE `TOBAPbl`(
`id_TOBAPA` INTEGER PRIMARY KEY,
`HAZBAHuE` TEXT,
`MODELb` TEXT,
`APTuKyL` TEXT,
`KPATHOCTb` INTEGER,
`DOCTynHIOCTb` INTEGER,
`KAPTuHKA` TEXT,
`nPOuZBODuTELb` TEXT,
`OnuCAHuE` TEXT,
`KATEGOPuia` INTEGER,
`tcEHA` INTEGER,
`CTATyC` TEXT,
`PEDAKTuPOBAHuE` TEXT
);
CREATE TABLE `ATTPu6yTbl`(
`id_ATPu6yTA` INTEGER PRIMARY KEY,
`HAZBAHuE` TEXT,
`Tun` TEXT
);

3 таблицы в SQLite3 файле, Так в пункте "#2", идёт запрос к "TOBAPbl_ATTPu6yTbl" чтобы получить атрибуты товаров(и в цикле, т.к. их несколько может быть, вывод в переменную). Т.е. на каждый товар идёт дополнительный запрос. Вот собственно и утечка времени. Собственно вопрос: решается это дело на уровне запроса?

Щас так:
Перед циклом вывода идёт обращение:

SELECT `id_TOBAPA`, `HAZBAHuE`, `MODELb`, `APTuKyL`, `KPATHOCTb`, `DOCTynHIOCTb`, `KAPTuHKA`, `KATEGOPuia`, `tcEHA` FROM `TOBAPbl`" + КатегорияКоманды0 + " LIMIT " + Количество_ВГруппе0 * n0 + ", " + Количество_ВГруппе0 * (n0 + 1)

КатегорияКоманды0 - длинная фигулина, список категорий(SQL синтаксис) из какой товары выдрать.
"Количество_ВГруппе0 * n0" и "Количество_ВГруппе0 * (n0 + 1)" - это для параллейности выполнения. Т.е.: программа работает в несколько потоков.



В самом цикле, идёт проход по товарам, если пункт #2 не закоментирован:

SELECT `id_TOBAPA`, `id_ATPu6yTA`, `ZHA4eHue` FROM `TOBAPbl_ATTPu6yTbl` WHERE `id_TOBAPA`='" + Товар.A + "' ORDER BY `id_ATPu6yTA` ASC

Собственно: ~ 2 минуты 30 секунд. Если закоментировать пункт #2 - 2-3 секунды.

Вопрос можно решить любым способом(в смысле: свобода действий, полная. Есть доступ ко всему).

Идея вертится у меня в голове: добавить колонку "id категории товара" в таблицу "TOBAPbl_ATTPu6yTbl", вот только как вытащить это дело в цикле?(т.к. за 1 проход в цикле будет виден 1 атрибут)
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39481076
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не интересная информация, но если важно:
- Причём данные из таблицы "ATTPu6yTbl" записаны в переменную до цикла.
- Перед созданием потоков - делается запрос, на выяснение "Сколько товаров в разделе", отсюда и деление на потоки. У каждого потока - своё соединение.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39481426
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще не будет никаких идей?
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39482128
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911,

Во-первых, индексов на TOBAPbl_ATTPu6yTbl.id_TOBAPA нет, исходя из вашего определения таблиц, скорее всего идёт FullScan по таблице. Если товаров сотни, и выполняется сотня запросов на выборку аттрибутов, то мы и имеем 100 раз просмотр одной и той же таблицы.

Во-вторых:
Если товаров до 100 (или "немного", тут по ситуации) то сгенерировать строку TOBAPbl_ATTPu6yTbl.id_TOBAPA in (1,2,3,4,5 ...) ID ваших выбранных товаров и без циклов выбирать.

Либо же лучший способ, сджойнить аттрибуты слева с товарами, отсеять по товарам и выбирать аттрибуты, если аттрибуты возвратят - NULL, значит ничего не сджойнилось, значит аттрибутов у конкретного товара нет.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39482446
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VSVLAD47911,

Во-первых, индексов на TOBAPbl_ATTPu6yTbl.id_TOBAPA нет, исходя из вашего определения таблиц, скорее всего идёт FullScan по таблице. Если товаров сотни, и выполняется сотня запросов на выборку аттрибутов, то мы и имеем 100 раз просмотр одной и той же таблицы.

Во-вторых:
Если товаров до 100 (или "немного", тут по ситуации) то сгенерировать строку TOBAPbl_ATTPu6yTbl.id_TOBAPA in (1,2,3,4,5 ...) ID ваших выбранных товаров и без циклов выбирать.

Либо же лучший способ, сджойнить аттрибуты слева с товарами, отсеять по товарам и выбирать аттрибуты, если аттрибуты возвратят - NULL, значит ничего не сджойнилось, значит аттрибутов у конкретного товара нет.
Я понимаю, это проблемно: поднять глаза и прочитать первые 3 сообщения. Но там, я процитирую себя, написано: "~326 000 товаров, планируется к выводу за раз - 1-2 миллиона, при этом общее количество товаров в таблице 'TOBAPbl' - 20 миллионов. На 1 товар - 0-10 атрибутов".

VSVLADЛибо же лучший способ, сджойнить аттрибуты слева с товарами, отсеять по товарам и выбирать аттрибуты, если аттрибуты возвратят - NULL, значит ничего не сджойнилось, значит аттрибутов у конкретного товара нет.
Ок. А можно конкретный пример? И, как я понимаю: это будет запрос "номер 2", т.е. для каждого товара, как следствие: будет сжирать время "Обращения к файлу - чтение - возврат результата". Поправьте, пожалуйста, если я ошибаюсь.

Дополнение: Не "аттрибутов", а "атрибутов". Сам допускал такие ошибки.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39484008
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообщем решил вопрос так:
Перед созданием таблицы "TOBAPbl" выполняется запрос к базе данных и берутся все атрибуты, и из них создаётся приписка, которая создаёт дополнительные колонки для таблицы "TOBAPbl". Т.е. эта таблица имеет колонки-атрибуты. Собственно вопрос: насколько это топорное решение? Если, например, будет таблица с 200 колонками - насколько всё будет плохо?
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39489512
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никто не может ответить по вопросу "Целесообразности" моего решения?
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39495252
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911,

Эх. Видимо не судьба. . .
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39495515
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911Вообщем решил вопрос так:
Перед созданием таблицы "TOBAPbl" выполняется запрос к базе данных и берутся все атрибуты, и из них создаётся приписка, которая создаёт дополнительные колонки для таблицы "TOBAPbl". Т.е. эта таблица имеет колонки-атрибуты. Собственно вопрос: насколько это топорное решение? Если, например, будет таблица с 200 колонками - насколько всё будет плохо?Это ужасное решение.
Атрибуты надо хранить в отдельной таблице, проиндексированной по полю "кому принадлежит атрибут".
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39497959
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дорогой White Owl, не будете ли вы так любезны: ответить мне на мой вопрос.
Копирую задачу, т.к. видимо мало кто смотрит с начала темы:
автор ТемыПредыстория вопроса:
Есть сайт, у него в базе данных хранятся товары, меня интересуют 2 таблицы: таблица товаров(название и т.д.) и характеристики товаров("id записи", "id атрибута", "Значение атрибута"). Т.е. все товары в 1 таблице, характеристики во 2.
Для моей программы я выбрал "SQLite3", для хранения данных в файле "База Данных", т.к. записей очень много, то и поэтому от "Хранения в памяти" я отказался.
Делаю я файл "SQLite3"(php скрипт на сервере. Также 2 таблицы, т.е. скопировал структуру таблиц), скачиваю, смотрю товары в разделе, радуюсь. Но вот вздумалось мне прикрутить фильтр. Потираю руки, делаю:
>>>>
Получаю список всех товаров(по количеству).
Делю его на количество процессоров, чтобы максимизировать скорость.
Цикл(Который делает "Свою группу товаров" - т.е. 1 поток):
1. Результат запроса(из 1-й таблицы, конкретный товар)
2. По его id я делаю запрос в этом же соединении на "список атрибутов"
3. Записываю в массив на вывод
>>>>
Тестовое количество товаров - ~326 000
Атрибуты: у кого-то 4, у кого-то 0.
Язык реализации: C#

Проблема: если с пунктом #2 - вывод на 6-ядерном компе - 2 минуты 30 секунд, если комментирую пункт "номер 2" - 3.5 секунды. Собственно вопрос: как выкрутится? т.к. планируется выводить 1-1.5-2 миллиона товаров. Я жду любые советы. Желательно с примерами.

Щас тест на другой базе. Атрибутов ~1300. Товаров 550 000. В самом разделе, понятное дело, будут не все атрибуты.

Собственно вопрос:
Как максимально быстро "высосать данные товара" и ввести их в список. Т.е. делать 2 запроса - очень плохо, т.к. будет по факту 2 цикла:
1) проходимся по товарам.
2) на каждый товар делаем запрос атрибутов, и запускаем цикл обработки результата запроса.

Как мне надо организовать тогда мою "базу данных"?

Буду очень благодарен за любую помощь.
White OwlАтрибуты надо хранить в отдельной таблице, проиндексированной по полю "кому принадлежит атрибут".
Можно по конкретнее, с примером? Я по PHP\C# больше, чем в SQL. Да и программа как раз: результат работы скрипта на сервере(PHP) -> в программу на C#.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39497961
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К слову. Атрибутов может быть(видов) 1300. А сама таблица "Атрибуты товара"(в смысле: IdТовара->idАтрибута->Значение) имеет более 10 000 000 значений.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39497963
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тест* показывает: моя идея - плохая. Собственно: кто чем может помочь?
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498053
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911Как максимально быстро "высосать данные товара" и ввести их в список. Т.е. делать 2 запроса - очень плохо, т.к. будет по факту 2 цикла:Не будет.
У тебя в реальности всего два варианта работы:
А) Обработка одного товара: запрос на одну строку товара и запрос на все его аттрибуты, после которого один цикл на отображение результата.
Б) Обработка всех товаров имеющих конкретный аттрибут: один коррелированый запрос по двум таблицам и один цикл на отображение результата.

Вложенные циклы которых ты боишься это то что называется "преждевременной оптимизацией" и не стоят внимания.

47911White OwlАтрибуты надо хранить в отдельной таблице, проиндексированной по полю "кому принадлежит атрибут".
Можно по конкретнее, с примером? Я по PHP\C# больше, чем в SQL. Да и программа как раз: результат работы скрипта на сервере(PHP) -> в программу на C#. 13601944
А с точки зрения прикладника: оставь обработку данных серверу. C# только для показа данных и внесения изменений. Если у тебя что-то обрабатывается в C# - значит ты уже делаешь не правильно. Все что в твоем коде должно быть это формирование запросов на UPDATE/DELETE и их запуск. Никаких циклов по данным быть не должно вообще.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498056
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911К слову. Атрибутов может быть(видов) 1300. А сама таблица "Атрибуты товара"(в смысле: IdТовара->idАтрибута->Значение) имеет более 10 000 000 значений.
Ну и сделай себе таблицу атрибутов:
Код: sql
1.
2.
3.
4.
5.
6.
create table attributes (
   id_product integer not null references products(id),
   id_attribute integer not null references attribute_description(id),
   attibut_value text null,
   primary key (id_product, id_attribute)
);

Включаешь поддержку внешних ключей, добавляешь on conflict по вкусу, первичный ключ тебе автоматом индекс построит и все собственно. Ну может еще тип ссылок может быть текстовый если id в ведущих таблицах текстовые.

А десяток миллионов это такие мелочи...
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498552
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl,
Сервер - только "Модуль работающий с SQLite3 файлом". Всё остальное вертится в программе.
Ссылки - благодарю. Про "REFERENCES" тоже. В течении суток посижу и посмотрю "что к чему".
И тем не менее, если это вам поможет представить ситуацию:
Программа работает на компе пользователя. И, скажем, список из 50 категорий -> 200 000 товаров она должна вывести "в одно мнгновение". А в перспективе: - 1.5 миллиона строк. Проблема как раз в атриутах: т.к. "Доп запрос к таблице "attributes"" - как раз самая тормозящая часть. Поэтому тема была поднята. Ключи(REFERENCES) должны помочь. Но что-то мне подсказывает: что надо всётаки избавиться от "дополнительных запросов атрибутов". Причём - "в таблице Товаров" - содержится всё: название, цена, описание(не маленькое, с HTML, на пол листа А4 точно, а то и больше).

Тут пришла в голову идея "Предварительной индексации": во время создания базы для проги, на стороне сайта: делается таблица, содержащая "id категории -> id товаров(ей принадлежащих)". Это ускорить должно вывод.

Щас вертиться извращённая идея:
Мол для каждого раздела будем создавать таблицу с атрибутами, вида "ТаблицаРазделаХ", Х - id раздела. И там колонки: "id товара", "Атрибут1", "Атрибут2" и т.д. По идее это должно разгрузить нагрузку и быть "Максимльно быстрым". Собствено вопрос: идея дурацкая?

Моё требование: максимальная скорость работы. Изощряться я готов по всякому. Любые извращения я готов рассмотреть. Да - я люблю извращения! (*:
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498554
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сервер*:
я не знаю насколько уместно назвать это:

SQLiteConnection Соединение = new SQLiteConnection(string.Format("Data Source={0};", БазаДанных["Основное"]));
SQLiteCommand Команда;
SQLiteDataReader Ответ;

Сервером. т.к. это лишь команды, которые помогают лезть в файл. Я так, к слову.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498574
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911White Owl,
Сервер - только "Модуль работающий с SQLite3 файлом". Всё остальное вертится в программе.И что? Модуль по твоему не может быть сервером?

47911Ключи(REFERENCES) должны помочь.Не помогут. Потому что это совершенно из другой области. REFERENCES это синтаксическое описание целостности данных, которая не даст тебе создать атрибут для несуществующего товара или удалить товар пока для него существуют атрибуты. На скорость чтения и поиска атрибутов или товаров это никак не скажется.

47911 Но что-то мне подсказывает: что надо всётаки избавиться от "дополнительных запросов атрибутов". Причём - "в таблице Товаров" - содержится всё: название, цена, описание(не маленькое, с HTML, на пол листа А4 точно, а то и больше).С точки зрения аналитики - чем у же таблица (меньше полей, и поля меньшей ширины) тем быстрее делается аналитика по этой таблице.
А если ты свои "товары" только показываешь на экране, но никогда не пытаешься как-либо просуммировать, то таблица "товаров" может быть насколько угодно широкой.

47911 Тут пришла в голову идея "Предварительной индексации": во время создания базы для проги, на стороне сайта: делается таблица, содержащая "id категории -> id товаров(ей принадлежащих)". Это ускорить должно вывод.Если "товары", можно сгруппировать в "категории", типа апельсины и яблоки это "фрукты", а столы и стулья это "мебель", то таблица "категорий" естественно будет нужна. Но это всего-лишь другой уровень абстракции "товаров". На отношения между "товарами" и "атрибутами", введение "категорий" никак не повлияет.


47911 Щас вертиться извращённая идея:
Мол для каждого раздела будем создавать таблицу с атрибутами, вида "ТаблицаРазделаХ", Х - id раздела. И там колонки: "id товара", "Атрибут1", "Атрибут2" и т.д. По идее это должно разгрузить нагрузку и быть "Максимльно быстрым". Собствено вопрос: идея дурацкая?Этот прием называется "Partitioning Data" (секционирование данных). Он может помочь на гигантских объемах, но... В твоем случае это будет лишним, ты потеряешь намного больше времени на поддержку секционирования, чем выиграешь на меньших секциях.
Вот когда твои 10 миллионов записей превратятся в десяток триллиардов, тогда будет смысл вернуться к этой идее. А пока тебе хватит правильного описания таблиц, вместо того ужаса что ты продемонстрировал в 20606505 .

47911 Моё требование: максимальная скорость работы. Изощряться я готов по всякому. Любые извращения я готов рассмотреть. Да - я люблю извращения! (*:Не стоит их любить. Стоит любить учебники.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498580
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911Сервер*:
я не знаю насколько уместно назвать это:

SQLiteConnection Соединение = new SQLiteConnection(string.Format("Data Source={0};", БазаДанных["Основное"]));
SQLiteCommand Команда;
SQLiteDataReader Ответ;

Сервером. т.к. это лишь команды, которые помогают лезть в файл. Я так, к слову.То что ты чувствуешь за этими командами конкретный файл это хорошо.
Но тем не менее, ты лично не контролируешь что происходит внутри SQLiteCommand и SQLiteDataReader. Ты отдал туда команду, получил оттуда ответ. А это (команда-ответ, команда-ответ) и есть главный определяющий принцип клиент-серверной архитектуры.
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498597
47911
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl,

White OwlЕсли "товары", можно сгруппировать в "категории", типа апельсины и яблоки это "фрукты", а столы и стулья это "мебель", то таблица "категорий" естественно будет нужна. Но это всего-лишь другой уровень абстракции "товаров". На отношения между "товарами" и "атрибутами", введение "категорий" никак не повлияет.

влияет в том плане, что мне не надо будет делать запрос вида "WHERE idКатегории=" . . . и перечислять 50(а то и более) категорий и ждать когда оно мне список предоставит. Мне надо проходить циклом по "Списку id товаров" и на каждый запрашивать все данные.

Вот только щас подумал: а не херню ли я творю. . .

К слову: планируется 20-30 миллионов товаров всего. В теории: будет расти.

Если привести текущие данные для эксперимента:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
CREATE TABLE `TOBAPbl`(
						`id_TOBAPA` INTEGER PRIMARY KEY,
						`HAZBAHuE` TEXT,
						`MODELb` TEXT,
						`APTuKyL` TEXT,
						`KPATHOCTb` INTEGER,
						`DOCTynHIOCTb` INTEGER,
						`KAPTuHKA` TEXT,
						`nPOuZBODuTELb` TEXT,
						`OnuCAHuE` TEXT,
						`KATEGOPuia` INTEGER not null REFERENCES KATEGOPuu(id_KATEGOPuu),
						`tcEHA` INTEGER,
						`CTATyC` TEXT,
						`BPEMia_HA4ALO` INTEGER,
						`BPEMia_KOEtc` INTEGER,
						`AKtcuia_HA4ALO` INTEGER,
						`AKtcuia_KOEtc` INTEGER,
						`PEDAKTuPOBAHuE` TEXT
);

CREATE TABLE `ATTPu6yTbl`(
						`id_ATPu6yTA` INTEGER PRIMARY KEY,
						`HAZBAHuE` TEXT,
						`Tun` TEXT
						);

CREATE TABLE `TOBAPbl_ATTPu6yTbl`(
						`id_TOBAPA` INTEGER not null REFERENCES TOBAPbl(id_TOBAPA),
						`id_ATPu6yTA` INTEGER not null REFERENCES ATTPu6yTbl(id_ATPu6yTA),
						`ZHA4eHue` TEXT,
						primary key (id_TOBAPA, id_ATPu6yTA)
						);


В программе C#(Если конечно это имеет значение):
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
            Task task1 = new Task(() => {
                bool OLLlu6Ku_LOG = false, Мои_Объявления = false;
                stopWatch.Start();
                _HACTPOiKu["Прогресс_Максимум"] = КоличествоЗаписей.ToString();
                _HACTPOiKu["Прогресс_с_чем"] = "Строим список товаров.";
                nPOGPECC_nOLOCA.Dispatcher.Invoke(_F_nPOGPECC_MAKCuMyM);

                SQLiteConnection Соединение = new SQLiteConnection(string.Format("Data Source={0};", БазаДанных["Основное"]));
                SQLiteCommand Команда; SQLiteDataReader Ответ;

                _HACTPOiKu["Прогресс_с_чем"] = "Обрабатываем \"Базу Данных\": Файл: " + БазаДанных["Основное"];
                nPOGPECC_nOLOCA.Dispatcher.Invoke(_F_nPOGPECC_O6HOBLEHuE);
                OLLlu6Ku += "\n" + System.IO.Path.GetFileName(БазаДанных["Основное"]);

                string КатегорияКоманды;
                    КатегорияКоманды = " WHERE `KATEGOPuia`='" + CnuCOK_KATEGOPui_B_PAZDELE[Активный_Раздел][0] + "'";
                    foreach (string a in CnuCOK_KATEGOPui_B_PAZDELE[Активный_Раздел])
                    {
                        if (!OLLlu6Ku_LOG) { OLLlu6Ku_LOG = true; continue; }//Пропускаем первую категорию
                        КатегорияКоманды += " OR `KATEGOPuia`='" + a + "'";
                    }
                КатегорияКоманды = " WHERE `KATEGOPuia`='62'";
				//В переменной "КатегорияКоманды" храниться фигулина: WHERE `KATEGOPuia`='' OR WHERE `KATEGOPuia`='' - все категории раздела.
				
                try
                {
                    КоличествоПотоков = Convert.ToInt16(CTPOKA_nOTOKu.Text);
                }
                catch
                {
                    CTPOKA_nOTOKu.Dispatcher.BeginInvoke(new Action(delegate ()
                    {
                        КоличествоПотоков = Convert.ToInt16(CTPOKA_nOTOKu.Text);
                    }));
                }
                TOBAPbl_CnuCOK_KyCKu = new List<ExpandoObject>[КоличествоПотоков];//Массив: для каждого потока - свой массив.

                Команда = new SQLiteCommand("SELECT count(`id_TOBAPA`) FROM `TOBAPbl`" + КатегорияКоманды, Соединение);
                Соединение.Open();
                КоличествоЗаписей += Convert.ToInt64(Команда.ExecuteScalar(CommandBehavior.CloseConnection));//Получаем количество записей. Странно: даже это тормозит. Но на тестовых данных(Тест с 300 000 товарами) не тормозило. А в Текущем тесте(550 000 товаров) - тормозит значительно
				//ВОТ ТУТ НАЧИНАЮТСЯ ТОРМОЗА - строкой выше.
				
                if (КоличествоЗаписей <= 0) { MessageBox.Show("В разделе не найдены товары.", "Вывод не возможен.", MessageBoxButton.OK, MessageBoxImage.Information); return; }

                Int64 Количество_ВГруппе = КоличествоЗаписей / КоличествоПотоков;//Сколько будет в "Целой группе 'товаров'". Типо: 4 групп по 200 товаров
                Int64 Количество_Остаток = КоличествоЗаписей % КоличествоПотоков;//Остаток от деления, т.е. сколько будет в "Последней группе товаров"
                int n = 0;

                Dictionary<string, string> Атрибуты_Товаров = new Dictionary<string, string>();
                string KOLOHKu = "";
                Команда = new SQLiteCommand("SELECT `id_ATPu6yTA`, `HAZBAHuE`, `Tun` FROM `ATTPu6yTbl` WHERE 1=1 ORDER BY `id_ATPu6yTA` ASC", Соединение);
                Соединение.Open();
                Ответ = Команда.ExecuteReader();
                foreach (DbDataRecord t in Ответ)
                {
                    Атрибуты_Товаров[t["id_ATPu6yTA"].ToString()] = t["HAZBAHuE"].ToString();
                    if (!Список_Колонок_Список_Атрибутов.ContainsKey(t["id_ATPu6yTA"].ToString()))
                    {
                        Список_Колонок_Список_Атрибутов[t["id_ATPu6yTA"].ToString()] = new Dictionary<string, string>();
                        Список_Колонок_Список_Атрибутов[t["id_ATPu6yTA"].ToString()]["Название"] = t["HAZBAHuE"].ToString();
                        Список_Колонок_Список_Атрибутов[t["id_ATPu6yTA"].ToString()]["Z"] = "";
                        KOLOHKu += ", KOLOHKA" + t["id_ATPu6yTA"].ToString();
                    }
                }
                Соединение.Close();

                for (n = 0; n < КоличествоПотоков; n++)
                {//Начинаем паралейную обработку
                    int n00 = n;//Временная переменная. Должна исключить ошибку "индекс за границами диапазона"
                                //Открываем новый поток
                    Task.Factory.StartNew(() => {
                        string КатегорияКоманды0 = КатегорияКоманды, Команда_Строка0, ФайлБазыДанных = БазаДанных["Основное"];
                        int n0 = n00; double Количество_ВГруппе0 = Количество_ВГруппе;
                        SQLiteCommand Команда0; SQLiteDataReader Ответ0, Ответ1;
                        SQLiteConnection Соединение0 = new SQLiteConnection(string.Format("Data Source={0};", ФайлБазыДанных));
                        if (n0 >= КоличествоПотоков) { n0 = КоличествоПотоков - 1; }
                        TOBAPbl_CnuCOK_KyCKu[n0] = new List<ExpandoObject>();

                        Команда_Строка0 = "SELECT `id_TOBAPA`, `HAZBAHuE`, `MODELb`, `APTuKyL`, `KPATHOCTb`, `DOCTynHIOCTb`, `KAPTuHKA`, `KATEGOPuia`, `tcEHA` " + KOLOHKu + " FROM `TOBAPbl`" + КатегорияКоманды0 + " LIMIT " + Количество_ВГруппе0 * n0 + ", " + Количество_ВГруппе0 * (n0 + 1);
                        Соединение0.Open();
                        Команда0 = new SQLiteCommand(Команда_Строка0, Соединение0);
                        //MessageBox.Show(Команда_Строка + "\nЦелыеГруппы=" + Количество_ВГруппе + "\nn0="+ n0 + "\nКоличествоПотоков="+ КоличествоПотоков + "\nОстаток="+ Количество_Остаток + "\n" + "\n" + "\n" + "\n");
                        Thread.Sleep(100);
                        Ответ0 = Команда0.ExecuteReader();//ВОТ ТУТ НАЧИНАЮТСЯ ТОРМОЗА. Выполнение запроса - самое "сложное место".
                        dynamic Товар = new ExpandoObject(); DataRow Строка;
                        foreach (DbDataRecord t in Ответ0)
                        {
                            if ((t["HAZBAHuE"].ToString()).Trim().Length < 1) { continue; }

                            KAPTuHKA = GLABHAia_KAPTuHKA(t["KAPTuHKA"].ToString());
                            Товар = new ExpandoObject();

                            HAZBAHuE = t["HAZBAHuE"].ToString();
                            Товар.Объявление = "Нет";
                            КоличествоВКорзине = 0;
                            if (B_KOPZuHE.ContainsKey(t["id_TOBAPA"].ToString())) { КоличествоВКорзине = B_KOPZuHE[t["id_TOBAPA"].ToString()]; }

                            Товар.A = t["id_TOBAPA"].ToString();
                            Товар.CKLAD = Convert.ToInt32(t["DOCTynHIOCTb"]);
                            Товар.KPATHOCTb = Convert.ToInt32(t["KPATHOCTb"]);
                            Товар.TOBAP_HAZBAHuE = HAZBAHuE;
                            Товар.TOBAP_KAPTuHKA = KAPTuHKA;
                            Товар.TOBAP_KOD = t["APTuKyL"].ToString();
                            Товар.TOBAP_tcEHA = t["tcEHA"].ToString();
                            Товар.ZAKAZ = КоличествоВКорзине;
                            Товар.А_Категория = t["KATEGOPuia"].ToString();
                            Товар.Категория = KATEGOPuu[t["KATEGOPuia"].ToString()]["uMia_nOLHOE"];

                            //Берём атрибуты товара
                            Команда_Строка0 = "SELECT `id_TOBAPA`, `id_ATPu6yTA`, `ZHA4eHue` FROM `TOBAPbl_ATTPu6yTbl` WHERE `id_TOBAPA`='" + Товар.A + "'";
                            Команда0 = new SQLiteCommand(Команда_Строка0, Соединение0);
                            Ответ1 = Команда0.ExecuteReader();
                            //c = 1;
                            foreach (DbDataRecord t1 in Ответ1) {
                                 ((IDictionary<String, Object>)Товар).Add("KOLOHKA" + t1["id_ATPu6yTA"].ToString(), t1["ZHA4eHue"].ToString());
                                Список_Колонок_Список_Атрибутов[t1["id_ATPu6yTA"].ToString()]["Z"] = "z";// Нужна для создание колонок-атрибутов в Контроле, который отображает товары. Типо: Название, Артикул, Цена, Атрибут 1, Атрибут 2, Атрибут 3
                            }

                            TOBAPbl_CnuCOK_KyCKu[n0].Add(Товар);
                        }
                        Соединение0.Close();
                    }, TaskCreationOptions.AttachedToParent);
                }//Проход цикла
            });
            task1.ContinueWith((t) => {
				//Когда получили весь список товаров. тут проблем нет. Смотрю время, делаю вывод товаров. + "До создаю не существующие колонки-атрибуты"
            });
            task1.Start();



Место тормоза можно найти по комментарию: "ВОТ ТУТ НАЧИНАЮТСЯ ТОРМОЗА"(я знаю, неожиданый комментарий.)

Код программы даю: для представления ситуации.
Сервер, с которого делается база SQLite(3.8.11.1) - является "MariaDB". Первые тесты проводились на сервере "Mysql"->SQLite(3.8.11.1).
Если дело не в моих запросах - то может в ПО?(Мой мозг говорит: накосячил в SQL. Где? Потому, что когда я смотрю на таблицы в SQLite - я вижу структуру такуюже, как и на сайте. На сайте стоит OpenCart.)

Модератор: пользуйся тэгом SRC
...
Рейтинг: 0 / 0
Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
    #39498643
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
47911Мне надо проходить циклом по "Списку id товаров" и на каждый запрашивать все данные.ЗАЧЕМ??? Я действительно не понимаю зачем это делать.
Скажи четко и без лирических отступлений: что ты хочешь получить в итоге от этого списка товаров?

47911Если привести текущие данные для эксперимента:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
CREATE TABLE `TOBAPbl`(
						`id_TOBAPA` INTEGER PRIMARY KEY,
						`HAZBAHuE` TEXT,
						`MODELb` TEXT,
						`APTuKyL` TEXT,
						`KPATHOCTb` INTEGER,
						`DOCTynHIOCTb` INTEGER,
						`KAPTuHKA` TEXT,
						`nPOuZBODuTELb` TEXT,
						`OnuCAHuE` TEXT,
						`KATEGOPuia` INTEGER not null REFERENCES KATEGOPuu(id_KATEGOPuu),
						`tcEHA` INTEGER,
						`CTATyC` TEXT,
						`BPEMia_HA4ALO` INTEGER,
						`BPEMia_KOEtc` INTEGER,
						`AKtcuia_HA4ALO` INTEGER,
						`AKtcuia_KOEtc` INTEGER,
						`PEDAKTuPOBAHuE` TEXT
);

CREATE TABLE `ATTPu6yTbl`(
						`id_ATPu6yTA` INTEGER PRIMARY KEY,
						`HAZBAHuE` TEXT,
						`Tun` TEXT
						);

CREATE TABLE `TOBAPbl_ATTPu6yTbl`(
						`id_TOBAPA` INTEGER not null REFERENCES TOBAPbl(id_TOBAPA),
						`id_ATPu6yTA` INTEGER not null REFERENCES ATTPu6yTbl(id_ATPu6yTA),
						`ZHA4eHue` TEXT,
						primary key (id_TOBAPA, id_ATPu6yTA)
						);

У тебя глаза не болят от такого стиля именования?


47911В программе C#(Если конечно это имеет значение):Да фиг его знает. Тут столько всего намешано, и таймер, и настройки, и потоки, и глазоломательные имена, и кириллические имена... выискивать в этом кошмаре SQL запросы совершенно не тянет.

47911Место тормоза можно найти по комментарию: "ВОТ ТУТ НАЧИНАЮТСЯ ТОРМОЗА"(я знаю, неожиданый комментарий.)А там C# код? Если да, то воспользуйся отладчиком, он встроен в Студию. А если тормозит SQL код, то может ты все-же покажешь конкретно этот SQL запрос?

47911Код программы даю: для представления ситуации.
Сервер, с которого делается база SQLite(3.8.11.1) - является "MariaDB". Первые тесты проводились на сервере "Mysql"->SQLite(3.8.11.1).
Если дело не в моих запросах - то может в ПО?(Мой мозг говорит: накосячил в SQL. Где? Потому, что когда я смотрю на таблицы в SQLite - я вижу структуру такуюже, как и на сайте. На сайте стоит OpenCart.)ээээ.... я даже не знаю что ответить на это.
Звучит это все в духе: Вот там в гараже стоит мотоцикл который трактор, а проверялось все на самолет-мотоцикле, почему оно все плохо плавает?
SQLite, MariaDB и MySQL это три чрезвычайно разные СУБД. Общего у них только то что они все СУБД и все они поддерживают базовый SQL диалект.
...
Рейтинг: 0 / 0
25 сообщений из 39, страница 1 из 2
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Проблема: получить товар и его характеристики(атрибуты) максимально быстрым способом.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]