Оптимальная реализация поиска и сортировки объектов с фиксированным количеством полей?

Есть объект с фиксированным количеством полей.

Необходимо реализовать поиск по заранее неизвестному количеству полей и сортировку по одному из полей.


Допустим есть поля field1, field2 и field3. В один момент времени может потребоваться поиск только по field1, в другой — по field1 и field3, в третий по всем вместе, и одновременно с этим нужна возможность сортировки по одному из этих полей.


Каково решение? Не хочется перегружать таблицу большим количеством индексов перебирая все возможные варианты фильтра (полей в реальной задаче 15)


Исходные данные: mySQL и PHP


Как я вижу решение:

создать один общий индекс

1) index idx1(field1, field2, field3)

и по одному индексу на каждое поле, в котором нужна сортировка:

2) index idx2(field2)

3) index idx3(field3)


Итого доступна сортировка по каждому из 3-х полей, плюс полный поиск


А запрос формировать так, чтобы всегда использовались все компоненты индекса.

Т.е. если нужен поиск только по field2 и field3, а поле field1 например foreign key (int, unsigned, null), т.е. не может быть 0, то where должно получиться следующим:


field1 > 0 AND field2 = 'searchValue2' AND field3 = 'searchValue3'


И так далее, для всех вариантов поиска.


Этот велосипед можно считать правильным решением?
  • Вопрос задан
  • 3232 просмотра
Пригласить эксперта
Ответы на вопрос 3
@ShouldNotSeeMe
Если столбцов много (миллионы-миллиарды), то обычный подход с индексами и WHERE не подойдет. Не так давно я сталкивался с подобной проблемой. Варианты я вижу такие:
1. Sphinx. Предназначен для полнотекстового поиска, но может искать и только по числовым полям (при docinfo=extern). Если записей в базе много, то он сильно расходует память. Работает быстро.
2. Таблицы в памяти. Аналогично п. 1.
3. EAV или хранение каждого поля в отдельной таблице. Немного медленнее, если пользователь задал мало параметров, и намного — если много.
4. OLAP-подобные способы. Самые большие требования к памяти и к дисковому пространству (при большом количестве вариантов — запредельные), но быстрый поиск по большому количеству параметров.
Для себя я решил, что оптимальный вариант — это Sphinx (docinfo=inline) при необходимости текстового поиска, а при отсутствии такой необходимости — комбинированный вариант п. 3 и 4, т.е. OLAP-подобная индексация работает только для наиболее частых вариантов полей.
Ответ написан
AxisPod
@AxisPod
Sphinx и не стоит что-то придумывать, в добавок есть SphinxQL, что сильно облегчает миграцию. У нас более миллиона записей, довольно объемных, ищет очень быстро.
Ответ написан
@egorinsk
Ха, делаете поиск по пользователям в очередной недосоциальной сети или сайте знакомств? ну-ну, на майскуле с кучей индексов ваш поиск будет работать ровно до 10 000 пользователей. Вообще, стоило бы сначала изучить, какие параметры используют чаще для поиска, и делать индексы по ним.

С ростом числа юзеров, как вариант костыля на первое время, можно попробовать прикрутить сфинкс или какой-нибудь Lucene, но с ростом нагрузки все равно этот функционал придется выносить в отдельный кастомный модуль. Спросите у вконтактеров, например, как у них сделан поиск по людям (отдельным модулем на Си).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы