2. План презентации
1. Возможности систем в построении поиска и их
ограничения
• Полнотекстовый поиск
• Параметрический поиск
2. Вопросы производительности и актуальности
данных
• Асинхронное обновление индекса как баланс между
актуальностью и производительностью
• Практические рекомендации по использованию очередей
сообщений AMQP
6. Почему Sphinx
MySQL PostgreSQL Xapian Sphinx Solr CLucene
Скорость
индексации
314 КБ/с 522 КБ/с 1.36
МБ/с
4.5 МБ/с 2.75 МБ/с 3.8 МБ/с
Скорость
поиска
175 мс /
3.46 сек
28 мс / 2.1
сек
14 мс
/ 135
мс
7 мс / 75
мс
25 мс / 212
мс
10 мс / 212 мс
Размер
индекса
150 % 150 % 200 % 30 % 20 % 20 %
Интерфейс SQL SQL API API, SQL Веб-сервис API
Биндинги ∀ ∀ 9 6 + ∀ 8 3.5
Операторы
поиска
&*" &* &*"N-
~
&*"N-<Z &*"N-~ &*"N-~
Стеммеры Нет 15 15 15 31 15 + CJK
Стоп-слова,
синонимы
Нет Да Да Да Да Да
Soundex Нет Нет Нет Да Да Нет
Подсветка Нет Да Нет Да Да Да
14. Ошибки алгоритма
Алгоритм составлен таким образом,
что ошибки (некорректные
подстановки) в его работе возможны.
Вероятность ошибок обратно
пропорциональна числу слов в
словаре и основном индексе.
15. Альтернативы
• Реляционные СУБД с функцией
полнотекстовой индексации с
ограничением
функциональности
• Другие полнотекстовые движки
19. Параметрический поиск
• быстрый параметрический поиск по NoSQL БД с
использованием Redis
• параметрический поиск средствами MySQL
• параметрический поиск средствами PostgreSQL по
GIST- и GIN-индексам для полей типа Hstore и JSON
• параметрический поиск по полнотекстовому
индексу Sphinx
20. Почему Redis
• Гарантированная скорость
• Масштабируемость
• Удобные для решения задачи
встроенные операции
• Все данные в памяти
21. Реализация – структура
индекса
• Все документы разбиваются на категории с
одинаковым набором параметров
• Для каждой категории строится свой набор
индексов для каждой характеристики в формате
Характеристика: набор документов
• Для каждой категории для характеристик с
условно-бесконечным набором значений (цена)
документы разбиваются на диапазоны с примерно
равным числом элементов
22. Реализация –
получение результатов
• Пересечение множеств с одиночным выбором
средствами Redis
• Объединение множеств с множественным выбором
• Пересечение/объединение множеств с фильтром в виде
диапазонов
• Возможность сортировки средствами Redis через
временные ключи
• Дополнительная фильтрация результатов на стороне
приложения в случае, если есть фильтр по диапазонам
(может выполняться с использованием реляционной
СУБД)
23. Пример: Исходные данные
Продукт Цвет Жирность ID
Молоко Белый 2,5% 1
Молоко Белый 3,2% 2
Молоко Белый 4,5% 3
Кефир Белый 2,5% 4
Кефир Белый 3,2% 5
Масло Желтый 82,5% 6
Сметана Белый 15% 7
Сливки Белый 15% 8
26. Альтернативные
решения: Sphinx
• Можно использовать как универсальный
индекс
• Нет гарантированной производительности
• Другая модель данных
• Более ресурсоемкое увеличение числа
индексируемых атрибутов
27. Альтернативные
решения: MySQL
• Тут все плохо…
• Низкая скорость поиска (альтернатива – индексация
всего и handlersocket для прямого доступа к данным,
но в результате - сложная логика на стороне
приложения)
• Крайне затруднительное расширение модели
данных, которое в общем случае приведет к
блокировке больших таблиц
28. Альтернативные
решения: PgSQL
• А вот тут все достаточно хорошо
• Специализированные типы данных:
– Hstore
– JSON (начиная с версии 9.3)
• По сути – типичная реляционная модель данных с
одним специальным полем
• Быстрые GIST/GIN индексы (GIN индекс быстрее на
выборке и медленнее на вставке. Выбор зависит от
конкретной задачи)
29. Так что-же выбрать
• При выборе инструмента для обеспечения
параметрического поиска необходимо опираться
на следующие факторы
– Какая реляционная СУБД используется в проекте
(если используется)
– Используется ли внешняя система
полнотекстовой индексации, которую можно
задействовать
– Имеется ли NoSQL БД Redis в проекте
• Нельзя забывать, что подключение любого нового
движка к проекту должно быть оправдано
31. Вопросы производительности и
актуальности
• Как без потери производительности
получить оперативное обновление данных
• Как минимизировать «дополнительные»
операции при обновлении данных
(например, перестроение полнотекстовых
и NoSQL индексов)
32. … ничего сложного, просто
очереди
• При получении запроса на обновление
данных, обновляем данные в центральной
БД и даем внешним системам команду на
пересчет
• Пересчет будет происходить в фоновом
режиме и не будет сказываться на
времени выполнения самой процедуры
обновления данных