powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Связка ID категории - ID товара
9 сообщений из 9, страница 1 из 1
Связка ID категории - ID товара
    #39417433
st_st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По какому принципу делается связка ID категории - ID товара, если товаров и категорий много (в таблице 120 млн записей)? Товар может быть в нескольких категориях. Была идея привлечь патрициев, в принципе скорость немного увеличилась, но сделать нормальное партиционирование не удалось (пришлось делать PARTITION BY HASH), так как категорий у меня 40 тыс, а партиций MySQL максимум поддерживает 8192. Собственно проблема пока в COUNT(*) для фильтра на странице каталога товаров, чем больше товаров в категории, тем больше тупит COUNT(*), с небольшим количеством просто летает, а с 200 тыс товаров в категории уже жуёт секунд по 8. Индексы, избыточные индексы над primary key и прочие танцы с бубном пока ни к чему не привели. Может разбить по таблицам, одна категория = одна таблица? 40 тыс таблиц в базе насоздавать и джойнить затем в выборках необходимый раздел, хм...
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39417437
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
st_st,

Обычную таблицу связку многие-ко-многим пробовали?
Как часто изменяются данные?
Откуда вообще так много товаров? Что за предметная область?
Фильтр в каталоге только по категориям или есть и другой?
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39417448
st_st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftst_st,

Обычную таблицу связку многие-ко-многим пробовали?
Как часто изменяются данные?
Откуда вообще так много товаров? Что за предметная область?
Фильтр в каталоге только по категориям или есть и другой?

Данные изменяются не часто (товары редко меняют принадлежность к категориям, но всё же иногда это случается), в основном это добавление (при добавлении новых товаров, в эту таблицу соответствий тоже идёт insert). Товаров не много пока, 20 млн, плюс 40 тыс категорий, вот в итоге примерно 120 млн и набежало в таблицу соответствий. Сама таблица из себя представляет ID_Товара, ID_Категории c уникальным констрейнтом по обоим полям и индексами на каждом из них (innodb). Фильтр есть по ценам и другим свойствам, но они берутся из других таблиц, в которых меньше записей и особо так не тормозят, то есть если их выкинуть, то подсчёт по категориям особо не убыстряется. На входе есть ID категорий (обычно не более 20-ти), по ним надо посчитать количество товаров с учётом фильтров по ценам, поиску и т.д. Запрос примерно набросал по памяти, первой идёт большая таблица (таблица связки) и второй джойнится более мелкая, с товарами и ограничениями выборки, что-то типа такого (SQL_NO_CACHE - это для тестирования) -

Код: plsql
1.
2.
3.
4.
5.
SELECT SQL_NO_CACHE Categories.CategoryID, COUNT(*) AS cnt 
FROM Categories AS Categories 
INNER JOIN Products AS Products ON Products.ID=Categories.ProductID 
WHERE Categories.CategoryID IN (1,2,3,4,5) AND Products.Price>0 /* и остальные различные условия выборки */
GROUP BY Categories.CategoryID
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39417456
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
st_stСама таблица из себя представляет ID_Товара, ID_Категории c уникальным констрейнтом по обоим полям и индексами на каждом из них (innodb).Выглядит несколько громоздко. Покажите лучше DDL таблицы, чтобы не было разночтений.
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39417677
st_st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE `ProductCategories` (
  `ProductID` char(10) NOT NULL,
  `CategoryID` bigint(20) NOT NULL,
  UNIQUE KEY `unique_prcat_index` (`ProductID`,`CategoryID`),
  KEY `ProductID` (`ProductID`),
  KEY `CategoryID` (`CategoryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8



ProductID и CategoryID приходят со сторонних сервисов, первый - символьный (от 1 до 10-ти символов), второй bigint (в int не влазит). Констрейнт unique_prcat_index добавлен, чтобы незамусоривали таблицы (без них приходилось сидеть и вычищать дубликаты с таблиц). Вообще проблема одна - чем большее число возвращает COUNT(*), тем дольше тупит запрос. Если на одном разделе фильтр выдал count в 200 товаров, то запрос выполнится за 0.001 сек, а если на соседнем раздел выдаст 2 млн товаров, то запрос может висеть минут 20. Собственно даже простой SELECT COUNT(*) FROM table занимает 8 секунд. Здесь наверное только разбивать таблицы.
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39417679
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
st_st,

Сделайте из пары полей первичный ключ, а из этих же полей в обратном порядке - простой индекс.
Так объем хранимой (и, соответсвенно, кэшируемой информации) изрядно сократится.
Если версия MySQL достаточно свежая (не помню точно, 5.6 или 5.7), то просто индекс понадобится не из двух полей, а из одного - второго пол первичного ключа.
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39417680
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А после перестройки таблицы проверьте, что у вас достаточен размер innodb_buffer_pool_size, чтобы в него с запасом влезали все таблицы и индексы.
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39417862
st_st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ключи на тестовой таблице переделал, проверю что там поменялось с размером индексов и скоростью, innodb_buffer_pool_size выставлен по максимуму, но с ним проблема в другом - бд занимает примерно пол терабайта (с данными и индексами), а ОЗУ на сервере намного меньше. Попозже сделаю тестовый пример - сам запрос, explain, скорость выполнения и данные по обоим таблицам, может проблема окажется в чём-то другом.
...
Рейтинг: 0 / 0
Связка ID категории - ID товара
    #39418361
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
st_stбд занимает примерно пол терабайта (с данными и индексами), а ОЗУ на сервере намного меньше.Надо бы стремить одно к другому.
БД хорошо бы пересмотреть на предмет уменьшения, как, например, с таблицей выше.
А в innodb_buffer_pool_size надо уместить хотя бы "горячую" часть БД.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Связка ID категории - ID товара
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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