|
|
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Привет коллеги. Илья. Белая Сова. Дима-Т. Саша-Меркурий. Лётчик Петрав. Изопропил. Petalvik. Softwarer. Володя двухтысячный. Сидоров. Блажкович. Док. Зяма. Жук-Ботан и прочие почитателю скруля. Начинаем мозговой штурм. Мы оптимизируем поиск по EAV. В продолжение моего занудства по поводу EAV-модели и поиска товаров. Дима уже вкурсе. Для всех остальных - вводная: Дано: интернет магазин на базе классического стека LAMP (Здесь MySQL можно заменить на произвольную реляционную DBMS не важно какую. Главное - реляционную). Список товаров на более чем 10 000 позиций. Товары побиты на категории (например Холодильники, Плазмы, Печи e.t.c) Каждый товар обладает базовым набором характеристик таких как : код товара, название, описание, цена предложения, остаток на складе. (далее можно детализировать еще другие характеристики но в данном обсуждении они не особо важны. Нас будет интересовать следующий пункт). Каждый товар обладает расширенным набором характеристик которые имеют достаточно вольную спецификацию. Например для Плазмы - это диагональ экрана (''), поддержка FullHD, потребляемая мощность (Вт), разрешение (два числа) и т.п. список атрибутов в виде строкового название и значения произвольных типов. Количество расширенных характеристик изначально неизвестно. Тоесть их может быть до нескольких десятков. На уровне ТЗ предполагается что база использует модель EAV как наиболее дешевый и доступный способ реализовать список расширенных характеристик. Интернет-магазин находится под постоянной нагрузкой. Поисковые операции по товарам осуществляются каждую секунду. Клиенты магазина - люди нетерпеливые и желают очень быстро получать результаты своих поисков. Владелец магазина - борется за клиентов и желает создать самые комфортные условия для быстрой работы. UI магазина спроектирован таким образом что клиент ничего не вводит с клавиатуры а только отмечает checkboxes. Все вещественные характеристики товаров перед поиском разбиты на группы. Например диагональ плазмы. Пример: Код: sql 1. 2. 3. 4. 5. 6. Что-бы я здесь хотел обсудить. Возможные алгоритмы и структуры данных которые помогут ускорить поиск по модели EAV. Можно - доработки к PG и MySQL. Можно - различные варианты кешей. Можно - использование С/C++ в стеке LAMP. Текстовый поиск, деревья, JSON, и все что может быть полезно - приветствуется. На консистентность кеша и БД можно пока забить. Скорость важнее. Варианты покупки кластеров или облак мы здесь обсуждать не будем. Это банально и не является темой для Программирования. Мы будем обсуждать инженерный и творческий подход Ваш покорный слуга не является разработчиком интернет магазинов и поэтому рад будет услышать советы и предложения на тему того как это уже где-то реализовано. Очень прошу вас не кидать в меня ссылками в Git или SVN, т.к. на анализ и понимание готовых решений у меня уйдут месяцы и это никоим образом не способствует топику и не гарантирует удачи. Если вы сами разработали или участвовали в подобном - прошу вас кратко описать суть технологии. Итак начинаем brainstorm! С уважением mayton P.S. Поиск должен быть ультра-быстрым (с) :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 02:17 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Гулить по словам Faceted index/Faceted search. Вкратце - набор индексов по значениям категорий или отрезкам значений + оптимальное применение набора таких индексов. Умеет любой промышленный индекс сервер, бери любой на вкус, Solr, ElasticSearch, Sphinx, SearchTank. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 02:38 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
mayton , давай посчитаем... Список на 10к товаров. У каждого товара есть несколько характеристик (если посмотреть на том же яндекс-маркете, то в среднем у категории товара их там 20-30, редко более полусотни). К тому же крайне редко попадается характеристика с очень уж обширным диапазоном значений, лично я не видал ни одной, в которой количество значений превосходило бы 64 (или хотя бы приближалось к нему). Но если брать по максимуму... пусть 20к товаров по 50 характеристик, кодирование которых требует 64 битов, это получится порядка сотни мегабайт. Не самый большой объём. А с учётом того, что таблица строго RO - грузим копию таблицы в память, и вот тебе уже минус дисковая подсистема и прирост скорости. Далее. Стопудово у тебя уже есть статистики. Нас интересуют две. Первая - это частота использования той или иной характеристики для фильтрации. Вторая - это селективность характеристики. Это я к чему? к тому, что индексировать по всем возможным совокупностям характеристик - занятие совершенно безнадёжное, но вот выделить основные группы, индексация которых даст значительный эффект (частая применимость и высокая селективность) нужно. Очень желательно, если данных хватит, выделить пары, а то и тройки, самых востребованных групп характеристик для составных индексов. Индекс из совокупности более чем 3 полей, мне кажется, будет маловостребован, и будет работать исключительно префиксом из 2-3 полей - а тогда нафига козе баян? Что имеем в итоге. Работа чисто в памяти, индексный отбор достаточно высокой селективности, и всё это на сравнительно небольшом объёме данных. Не думаю, что скорость работы будет такова, что у посетителей будут поводы для недовольства, даже если использовать "младшие" СУБД (во всяком случае MySQL из лампы должен летать, хотя я бы рекомендовал собирать систему самостоятельно, а не ставить готовый комплекс, начальная настройка делается один раз), просто сервер БД нужно будет настроить должным образом, чтобы он не испытывал проблем ни с памятью под Memory-таблицы, кэш индексов и буферы сортировки, ни с количетсвом процессорного времени. А если претензии по скорости будут - то это будут претензии не к СУБД, а к другим компонентам системы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 08:08 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
fixxerГулить по словам Faceted index/Faceted search. Вкратце - набор индексов по значениям категорий или отрезкам значений + оптимальное применение набора таких индексов. Умеет любой промышленный индекс сервер, бери любой на вкус, Solr, ElasticSearch, Sphinx, SearchTank. Да, я например на Solr это щупал, отлично работает. (правда, Solr-индексы , да и все из этого списка наверное, они off-line, но не важно). В документации по Solr есть пример Web-APP где это просто тупо реализовано, можно изучать. Фасетный поиск встроен в Solr и имеется в его API. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 13:16 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Если честно не вижу тормозов с классической реляционной структурой. Накидал по-быстрому ТаблицаОписаниеCategoryСправочник категорийValueЗначения внутри категорииTovarСправочник товаровAttributeПривязка товаров к значениям Для ускорения выборок небольшая денормализация: продублировал cat_id из Value в Attribute А дальше выбираем таким запросом Код: sql 1. 2. 3. 4. 5. 6. 7. Не думаю что с твоими объемами будет дольше 10 мс выборка идти. Тем более что запрос отлично параллелится. Для ускорения выборки можно создать индекс (val_id, tov_id, cat_id) который полностью уберет обращения к таблице. Про размер: Предположим в среднем 50 атрибутов на товар, тогда по размеру Attribute получится примерно 500 000 записей, 16 байт на запись итого 8 Мб. Можно затестить, надо только генератор данных сделать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 13:25 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Dima T, С классической схемой проблема будет в том, что надо будет по всем полям таблицы товаров иметь возможность делать быстрый поиск по любому поднабору атрибутов и быструю агрегацию (подсчёт кол-ва товаров) также по любому набору атрибутов. Это возможно, но для этого нужно создавать очень много индексов, по всем сочетаниям атрибутов. Очевидно, что чем больше атрибутов, то тем больше их сочетаний, и тем больше будет индексов. Можно не создавать индексы на все сочетания, тогда надо либо чтобы таблица товаров была небольшой и влезала в кэш (несколько тысяч товаров и до 30-50 -- легко), либо чтобы фасетный поиск вёлся не произвольно, а предметно-ориентировано, тогда можно создавать только ведущие индексы. Применение EAV позволит об этом вообще не думать, но зато придётся думать о другом. :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 13:43 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
MasterZiv, внимательнее на структуру посмотри, там все уже есть и дополнительно ничего не надо. Все решается тем запросом, который я написал. Запрос строится динамически. Там пример как-будто выбран фильтр по 3-м категориям: КатегорияЗначения1123 537 для каждой категории отдельный подзапрос Код: sql 1. и в конце отбор только товаров попавших во все категории Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 13:54 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Dima T , ты явно толкаешь ТС в направлении динамического sql... не самый лучший выбор. А уж группировка несортированной объединённой выборки - если получится дофига записей и она захочет материализоваться, ты состаришься ждать результата. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 14:05 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Akina Dima T , ты явно толкаешь ТС в направлении динамического sql... не самый лучший выбор. ХЗ за что его так не любят. План для простых запросов быстро строится. Граблей с построением планов параметризованных запросов тоже полно. AkinaА уж группировка несортированной объединённой выборки - если получится дофига записей и она захочет материализоваться, ты состаришься ждать результата. Давай прикинем: допустим очень дотошный пользователь натыкает фильтр по 10 категориям, под одну 80% товаров, под другую 20% и т.д. Думаю в среднем 30-50% товаров на категорию, тогда 10*50%=500% товаров в конечной выборке, или 10000*500% = 50 000 записей. Как-то ни разу не дофига. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 14:23 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Привет коллеги. Отвечу всем чуть позже когда доберусь до нормальной клавиатуры. Всем спосибо за активность ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 15:00 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
maytonUI магазина спроектирован таким образом что клиент ничего не вводит с клавиатуры а только отмечает checkboxes. Все вещественные характеристики товаров перед поиском разбиты на группы. Это очень упрощает задачу. Главная таблица связи товаров с их характеристиками упрощается, поскольку значение характеристики представлено одним полем-ссылкой на справочник групп. Критерии в поисковом запросе сводятся к "Тип_характеристики=? and Группа_значения=?", что покрывается индексом. Отсутствие having в запросе позволяет нечёткий поиск по релевантности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 15:09 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Dima TMasterZiv, внимательнее на структуру посмотри, там все уже есть и дополнительно ничего не надо. Все решается тем запросом, который я написал. Запрос строится динамически. А, так это у тебя не классическая схема, а наоборот. Я прочитал "классическая", и дальше не глядел даже :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 17:15 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
MasterZivА, так это у тебя не классическая схема, а наоборот. Я прочитал "классическая", и дальше не глядел даже :-) Классическая в смысле что по всем правилам теории реляционных БД спроектировано. И без всякой экзотики типа JSON и т.д. Я к тому что это лишнее: maytonМожно - доработки к PG и MySQL. Можно - различные варианты кешей. Можно - использование С/C++ в стеке LAMP. Текстовый поиск, деревья, JSON, и все что может быть полезно - приветствуется. На консистентность кеша и БД можно пока забить. Скорость важнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 17:39 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Dima TХЗ за что его так не любят. План для простых запросов быстро строится.Планировщик - он один на инстанс сервера, и работает в одном потоке. При большом потоке запросов он запросто может стать узким местом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 18:54 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
AkinaDima TХЗ за что его так не любят. План для простых запросов быстро строится.Планировщик - он один на инстанс сервера, и работает в одном потоке. При большом потоке запросов он запросто может стать узким местом. Можно конкретики: где именно он однопоточный? О каком сервере речь? Я честно сознаюсь что в эту тему никогда не вникал, но не вижу проблем сделать его многопоточным. Тут нет ничего требующего однопоточности. План строится на статистиках, а они не очень меняются, да даже если и меняются и план будет построен на предыдущей статистике, то это просто проблема одного конкретного запроса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 19:24 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Dima T , речь о MySQL-сервере (автор изначально обозначил, что платформа событий - лампа). У него работает ОДИН процесс парсера-оптимизатора-планировщика на инстанс. Сколько бы процессов не было, сколько бы процессоров не стояло в системе. By design. И если запросы "короткие", но их дохрена, то они тупо построятся в очередь, ожидая обработки - с кэшированием плана у MySQL негусто. Насчёт проблем - боюсь, что проблем-таки есть у него. Не надо спрашивать, какие именно - не в курсе. Но вариантов масса. Начиная от того, что ядро изначально не предназначено, и кончая вульгарным "а кто это будет делать"... Оракл всё-таки не благотворительная организация. Изменяется ли алгоритм работы планировщика, если набирается такая очередь, скажем, в сторону упрощения ценой ускорения построения плана, пусть даже неоптимального - я не знаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 20:22 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Akina , соглашусь что MySQL редкостная хрень, но популярная. 10 лет назад сравнивал его с MSSQL и был в шоке: одни и те же запросы на порядок тормознее. Переписывал запросы. Сам с ним живу, твой аргумент еще один толчок уйти на что-то другое. Но пока он справляется с нагрузкой, потому дальше пользую. Но в ТЗ было по другому maytonЗдесь MySQL можно заменить на произвольную реляционную DBMS не важно какую. Главное - реляционную". Сегодня есть куча предложений того же постгреса. Не хочешь MySQL - замени. Нет ведь речи о готовом работающем проекте, на котором возникнут проблемы "переезда" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 20:39 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Ого тут текста. Ну ладно. Попробую ответить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 22:06 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Dima Tв ТЗ было по другомуНу тогда берём любую СУБД с олапкой - самая для него задача. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 22:33 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Если вариант Дмитрия не устраивает, в таком случае я также склоняюсь к BI, реляционный OLAP ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 22:55 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Прошу прощения за оффтоп. Дмитрий, не первый раз встречаю что атрибуты отношений имеют префикс относящийся к имени отношения, но никогда не понимал зачем это. Когда я спрашивал, мне говорили о том, что ребятам элементарно join ить удобно, однако разве кто-то используется JOIN без псевдонимов. В том случае, если один из атрибутов отношения является foreign key то я согласен с тем, что желательно добавить префикс указывающий на имя таблицы, в противном случае, мне до сих пор не понятно, зачем это нужно, видимо в силу малого опыта в области баз данных. Объясни пожалуйста для большинство все так делают, ибо это вопрос уже несколько лет лежит у меня в голове фоном))) Надеюсь что это холивар, если так, то удаляйте сразу мое сообщение, а то основная тема загнется ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 23:04 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Надеюсь что это НЕ холивар ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2016, 23:06 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
SashaMercuryПрошу прощения за оффтоп. Дмитрий, не первый раз встречаю что атрибуты отношений имеют префикс относящийся к имени отношения, но никогда не понимал зачем это. Когда я спрашивал, мне говорили о том, что ребятам элементарно join ить удобно, однако разве кто-то используется JOIN без псевдонимов. В том случае, если один из атрибутов отношения является foreign key то я согласен с тем, что желательно добавить префикс указывающий на имя таблицы, в противном случае, мне до сих пор не понятно, зачем это нужно, видимо в силу малого опыта в области баз данных. Объясни пожалуйста для большинство все так делают, ибо это вопрос уже несколько лет лежит у меня в голове фоном))) Надеюсь что это холивар, если так, то удаляйте сразу мое сообщение, а то основная тема загнется Не совсем понял о чем речь, если об использовании имени TOV_ID вместо ID для ключа таблицы, то тут на JOIN`е жизнь не заканчивается. Те же имена внешних ключей надо давать, если им каждый раз имя придумывать, то можно наплодить TOV_ID, TOVAR_ID и т.п., а так один раз назвал и тупо дублируешь название. Потом когда на клиенте обрабатываешь результат запроса ты уже не видишь откуда данное поле взялось. Если поле называется ID или NAME то надо в запрос смотреть, а так сразу понятно что такое TOV_ID откуда бы оно не взялось. В первых поделках у меня были имена ID, NAME и т.п. тоже не понимал нафига лишние буквы писать, потом когда размеры написанного выросли - понял что неудобно с такими именами работать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.12.2016, 11:46 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
Dima TMasterZivА, так это у тебя не классическая схема, а наоборот. Я прочитал "классическая", и дальше не глядел даже :-) Классическая в смысле что по всем правилам теории реляционных БД спроектировано. И без всякой экзотики типа JSON и т.д. Да, это лишнее, я согласен, но "классическая" -- это не EAV, а обычная горизонтальная таблица. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.12.2016, 14:02 |
|
||
|
Тяпничный поиск товаров по набору атрибутов
|
|||
|---|---|---|---|
|
#18+
fixxerГулить по словам Faceted index/Faceted search. Вкратце - набор индексов по значениям категорий или отрезкам значений + оптимальное применение набора таких индексов. Умеет любой промышленный индекс сервер, бери любой на вкус, Solr, ElasticSearch, Sphinx, SearchTank. Добрый день. Большое спасибо за терминологию. Ну... если фасетный - то пускай будет фасетный поиск. Я не против. По поводу промышленных индекс-серверов. Solr - это КМК платный продукт на базе технологий Apache Lucene и возможно еще кое-чего. C Apache Lucene я работал. Это full-text search. Достаточно сложный и избыточный механизм который созавался для various text и поиска релевантных документов в соответствии с Search Query. Использовать в данной задаче FTS я считаю немного избыточным т.к. стек у настоящего FTS очень длинный (есть фаза очистки оригинального текста и приведения его к каноническим формам) а у нас задача более простая. Найти товар по набору признаков. ElasticSearch - это ЕМНИП бесплатный вариант Solr (впрочем здесь я могу ошибаться пускай меня поправят). С продуктами Shinx, SearchTank я не сталкивался и незняю что это такое. Опять-же опираясь на свой тезис о простом стеке LAML я не хотел-бы переводить обсуждение этой задачи в обсуждение применения конкретного коробочного продукта. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.12.2016, 16:25 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=39368865&tid=1340536]: |
0ms |
get settings: |
8ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
260ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
83ms |
get tp. blocked users: |
1ms |
| others: | 242ms |
| total: | 619ms |

| 0 / 0 |
