Что быстрее индекс по varchar(255) или индекс по int(11)

babahalki

Постоялец
Регистрация
6 Май 2016
Сообщения
247
Реакции
107
Привет, друзья.
Решаю практическую задачу по оптимизации структуры БД. Делаю часть БД, касающуюся свойств товаров.
Что будет быстрее работать для
Код:
select col from table where col in (............)
Если col будет varchar(255) или int(11)?
 
Естественно int, и места индексы будут занимать гораздо меньше. Но вот на счет IN, на сколько мне известно, то мускуль не поддерживает индексы в данной конструкции.
 
Естественно int, и места индексы будут занимать гораздо меньше. Но вот на счет IN, на сколько мне известно, то мускуль не поддерживает индексы в данной конструкции.
спасибо, буду копать в эту сторону.
Тут посерьезнее проблема вылезла, был вариант со множеством left join сделать, вот тут точно без индексов получилось. Концепция множественности таблиц вообще неработоспособная выходит.
Получается вариант с наименьшим кол-вом джоинов - делать все в 1 таблицу. 64 индекса мускуль разрешает, должно хватить.
 
64 индекса мускуль разрешает, должно хватить.
Плохой вариант.
Похоже вы еще один, кто не знает как работают индексы.
1. Почитайте про покрывающие и составные индексы
2. Почитайте, почему много индексов - плохо. Со слов "не надо увлекаться созданием большого количества индексов" Для просмотра ссылки Войди или Зарегистрируйся
3. Почитайте, что такое профилирование запросов, и как их оптимизировать

Концепция множественности таблиц вообще неработоспособная выходит

А смотря в каких случаях. Вот положительный пример: у вас есть база пользователей, 1 млн штук. В среднем одна регистрация каждые 10 минут. "Логинятся" на сайте каждые 10 секунд.
Если время последнего логина писать в ту же таблицу, кеш запросов к этой таблице будет в среднем жить 10 секунд, так как любое обновление таблицы его сбрасывает. А если вынести в отдельную таблицу, и ее джойнить в некоторых местах - некоторые запросы к таблице пользователей будут жить до 10 минут.
Гуглить по "вертикальное партиционирование"
 
Если время последнего логина писать в ту же таблицу, кеш запросов к этой таблице будет в среднем жить 10 секунд, так как любое обновление таблицы его сбрасывает.
Я на кеш мускуля ставки бы не делал. Он в большей части вреден, чем полезен.
 
Я на кеш мускуля ставки бы не делал. Он в большей части вреден, чем полезен.

Я на кеш не рассчитываю, потому что повторяющиеся запросы будут достаточно редкими, почти все будут уникальными. Задача в том, чтобы заставить систему выполнять эти запросы максимально быстро.

Сделаю так:

s_products
id int(11)
name varchar(512)

s_features
id int(11)
name varchar(256)

s_values_uniq
id smallint(6)
value varchar(512)

s_options
product_id int(11)
1 smallint(6)
2 smallint(6)
3 smallint(6)
.
.

Типичный запрос на получение товаров с определенными свойствами и сразу самих товаров.
Код:
SELECT o.product_id, o.1, o.2, o.3
FROM s_options o
WHERE 1
AND o.1 = '12' AND o.2 = '10' AND o.3 = '1023'
Потом построчно проходим все записи из выборки и раскладываем все поля по отдельным массивам, фильтруя повторы и NULL, и заменяя значения id на значения из таблицы c уникальными значениями из таблицы s_values_uniq.

В итоге 1 выстрел и 2 зайца, у нас есть id нужных товаров, а также значения свойств соответствующие этим товарам.

Но идея с хранением в 1 супер таблице мне не нравится, какой-то большой excel получается. Интересно как хранит данные яндекс маркет?
 
1. Сразу указывайте в колонках NOT NULL - по возможности. Обработка колонок, в которых может быть NULL - дольше.
2. Вы изобретаете то, что называется EAV. Для самообразования это хорошо. На небольших данных будет отлично работать, какую бы схему не придумали. На больших - ну как сделаете. Я бы заранее подготовил данные, скажем 1 млн товаров, чтобы посмотреть как будет работать. А также несколько вариантов фильтрации. И тогда на этом можно начать "обкатывать".
Интересно как хранит данные яндекс маркет?
ХЗ, не буду говорить что не знаю.
Алиэкспресс раньше использовал MySQL. Яндекс почта - на PostgreSQL. Яндекс метрика - кликхаус.
У постгреса гораздо больше фич, чем у мускула. Например - поиск по JSON. Ну в Mysql эту фишку тоже впилили в версию 5.7, что относительно недавно. Можно и без таблиц искать, сразу по JSON. Единственное - сколько у вас товаров?

Также для поиска по характеристикам можно использовать фасетный поиск на основе Sphinx + его тип - MVA. Его главный разработчик в одном докладе так и сказал - все БД хороши для хранения и транзакций. А для поиска - не очень. Сфинкс покрывает эту задачу.
 
1. Сразу указывайте в колонках NOT NULL - по возможности. Обработка колонок, в которых может быть NULL - дольше.
2. Вы изобретаете то, что называется EAV. Для самообразования это хорошо. На небольших данных будет отлично работать, какую бы схему не придумали. На больших - ну как сделаете. Я бы заранее подготовил данные, скажем 1 млн товаров, чтобы посмотреть как будет работать. А также несколько вариантов фильтрации. И тогда на этом можно начать "обкатывать".

ХЗ, не буду говорить что не знаю.
Алиэкспресс раньше использовал MySQL. Яндекс почта - на PostgreSQL. Яндекс метрика - кликхаус.
У постгреса гораздо больше фич, чем у мускула. Например - поиск по JSON. Ну в Mysql эту фишку тоже впилили в версию 5.7, что относительно недавно. Можно и без таблиц искать, сразу по JSON. Единственное - сколько у вас товаров?

Также для поиска по характеристикам можно использовать фасетный поиск на основе Sphinx + его тип - MVA. Его главный разработчик в одном докладе так и сказал - все БД хороши для хранения и транзакций. А для поиска - не очень. Сфинкс покрывает эту задачу.

Делаю форк уже имеющейся CMS. Самообразование - побочный эффект. Нужна рабочая система в итоге. Товаров примерно 100 тыс.

За полтора года набралось некоторое количество мелких твиков, которые сейчас пытаюсь собрать во что-то более цельное.

Для просмотра ссылки Войди или Зарегистрируйся
 
100к товаров немного, даже если таблицу плохо сделать без индексов будет работать за норм время. Если товаров больше ляма, вот тогда нудно беспокоится. ( если конечно у вас используется hdd, то нужно хорошо продумать индексы)
 
1. Сразу указывайте в колонках NOT NULL - по возможности. Обработка колонок, в которых может быть NULL - дольше.
2. Вы изобретаете то, что называется EAV. Для самообразования это хорошо. На небольших данных будет отлично работать, какую бы схему не придумали. На больших - ну как сделаете. Я бы заранее подготовил данные, скажем 1 млн товаров, чтобы посмотреть как будет работать. А также несколько вариантов фильтрации. И тогда на этом можно начать "обкатывать".

ХЗ, не буду говорить что не знаю.
Алиэкспресс раньше использовал MySQL. Яндекс почта - на PostgreSQL. Яндекс метрика - кликхаус.
У постгреса гораздо больше фич, чем у мускула. Например - поиск по JSON. Ну в Mysql эту фишку тоже впилили в версию 5.7, что относительно недавно. Можно и без таблиц искать, сразу по JSON. Единственное - сколько у вас товаров?

Также для поиска по характеристикам можно использовать фасетный поиск на основе Sphinx + его тип - MVA. Его главный разработчик в одном докладе так и сказал - все БД хороши для хранения и транзакций. А для поиска - не очень. Сфинкс покрывает эту задачу.


Запилил на dynamiclight.ru 1 млн. товаров.
Я сделал дублирование всех уникальных полей у товаров через concat(name,1), От количества полей скорость работы не меняется.
Надо бы как-то усложнить тест.
<-------------- добавлено через 1765 сек. -------------->

Самым долгим стал некешируемый метод get_brands() ~6сек


Код:
explain SELECT b.id, b.name, b.url, b.meta_title, b.meta_keywords, b.meta_description, b.description, b.image FROM s_brands b WHERE 1 AND b.id in (SELECT brand_id FROM s_products p WHERE 1 AND p.visible=1 AND p.id in (SELECT product_id FROM s_products_categories WHERE category_id in ('7','97','128','208','6','277','314','341','39','71','137','217','231','70','83','111','135','143','283','361','82','89','382','88','96','98','238','304','379','5','20','99','358','19','30','33','46','47','65','100','121','129','145','149','154','207','221','225','232','258','266','267','275','295','318','359','29','51','64','381','172','174','243','261','280','328','331','289','305','50','118','203','216','260','308','357','380','117','171','175','291','378','170','253','296','298','252','4') ))
Вот что показывает explain:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE b ALL PRIMARY,id_name NULL NULL NULL 54 Using where
1 SIMPLE <subquery2> eq_ref <auto_key> <auto_key> 4 sevenlig_rapida.b.id 1 NULL
2 MATERIALIZED s_products_categories range PRIMARY,category_id category_id 4 NULL 437281 Using where; Using index
2 MATERIALIZED p eq_ref PRIMARY,brand_id,visible PRIMARY 4 sevenlig_rapida.s_products_categories.product_id 1 Using where

На 100 тысяч товаров делайте в одну таблицу, если у вас количество характеристик до 50 по одному id. Иначе больше времени будет уходить на соединение таблиц между собой при запросах.
Так и сделал. В 1 таблицу. Только я не понял, что значит: "до 50 по 1 id"?

Это как?
Как можно иначе? В 1 поле сразу по несколько id писать?
 
Последнее редактирование модератором:
Назад
Сверху