2017-01-30 3 views
0

установки:ThinkingSphinx group_by вызывает медленные поисковые запросы

  • Rails 4
  • MySQL
  • ThinkingSphinx

У меня есть модель (Record) в мое приложение с почти 500 миллионов строк. Эта модель имеет 32 поля, но только две, которые мне интересны для определенного поиска Sphinx: name и token. name - это то, что я ищу против использования Sphinx, и token - это то, что я хочу вернуть для выполнения других действий в Rails.

Моих индексов Настроенные:

ThinkingSphinx::Index.define :records, :with => :real_time do 
    # fields 
    indexes name 
    indexes token 

    # attributes 
    has token, as: :token_attr, type: :string 
    # < several additional attributes > 
end 

То, что я хочу сделать, это запрос на Sphinx :records согласования с name и его возвращает различныхtoken строки в массиве.

Вот что у меня есть:

Record.search("red", indices: %w(records), max_matches: num_tokens_i_need, group_by: :token_attr) 

... где num_tokens_i_need обычно где-то в тысячи (менее 10000)

выше запроса занимает от 5-8 минут. Однако, когда я просто сделать:

Record.search("red", indices: %w(records), max_matches: num_tokens_i_need).map(&:token).uniq 

Поиск невероятно быстро (возвращение нескольких миллионов записей в течение нескольких сотен миллисекунд), но я не вернусь num_tokens_i_need из-за .uniq вызова.

В основном, что мне нужно сделать, это быстрый поиск Сфинкса, который возвращает мне точное количество различных токенов для данного термина (например, «красный»).

Если вы видите мой sphinx.conf или что-нибудь еще, пожалуйста, сообщите мне.

+0

И если кто-то захочет объяснить, почему нисходящий, я был бы признателен. – CDub

ответ

0

Sphinx docs Обратите внимание, что группировка выполняется в памяти, поэтому для получения сгруппированных результатов поиска каждый атрибут документа должен находиться в памяти в какой-то момент. Учитывая, что в вашем индексе записи есть несколько миллионов документов, я предполагаю, что это причина медленности.

Имейте в виду, что в вашем втором примере миллионы записей могут соответствовать вашему запросу, но они не все возвращаются Sphinx (а соответствие выполняется исключительно по полям, атрибуты не задействованы), что часть того, почему этот запрос много быстрее.

Некоторые мысли о более эффективных путей вперед:

  • Если вы просто хочет лексемы из экземпляров записи, где имя соответствует точно, то SQL, вероятно, лучший инструмент для этой работы. Даже при частичных совпадениях использование нечеткого соответствия вашей базы данных может быть более быстрым.
  • Если вы только после номер токенов, а не значения токена, то Sphinx действительно не является подходящим инструментом для работы.Он не построен с учетом агрегации, поэтому почему он не настроен на запрос, который вы используете.
  • Если значения ключевых слов (в ваших примерах, red) являются известным набором (а не предоставленным пользователем), возможно, вы можете кэшировать значения и пересчитывать их на регулярной основе (один раз в день?).

Ни один из этих явных победителей, но, надеюсь, они помогут вам найти лучшее решение.

Смежные вопросы