Ранее я писала серии постов с разборами работы индексаторов radix и HAMT, но остался вопрос, что это даёт на реальных поисковых сценариях.
Поэтому я собрала небольшой benchmark suite в виде отдельного подпроекта и прогнала свой fts рядом с другими гошными индексаторами
bleve (не смейтесь) и blue на нескольких типах запросов:
term — поиск одного слова
and — несколько обязательных слов
or — несколько альтернативных слов
phrase — точная фраза
prefix — поиск по началу слова
Меня интересовало конкретно: время билда, размер индекса, время поиска, QPS и основные метрики качества выдачи: Recall@k, nDCG@k, MRR.
Radix
Radix-индексатор ожидаемо оказался очень сильным на prefix запросах за счет хранения ключей через общие префиксы - поэтому для него это почти нативный сценарий. В цифрах это примерно так:
p50: 0.003 ms
p95: 0.026 ms
p99: 0.062 ms
QPS: 126080
При этом индекс оказался самым компактным:
fts-engine radix: ~160 MB
blue: ~307 MB
bleve: ~690 MB
Но сам билд занял около
24.66s при скорости индексации - 2028 docs/s, что сильно медленее конкурентов. По остальным типам запросом radix не обогнал конкурентов. HAMT
Так как
fts позволяет менять индексаторы, переключилась на HAMT (спасибо Pavlo!!) для сравения. Он уже устроен иначе, так как путь к ключу определяется фрагментами хеша.
radix: BUILD 24.66s, docs/s 2028, INDEX ~160 MB
HAMT: BUILD 19.68s, docs/s 2541, INDEX ~175.5 MB
Видно, что HAMT стал быстрее строиться, индекс немного вырос, но всё ещё остался заметно меньше.
Тут нет большого выигрыша относительно radix, но HAMT обогнал конкурентов на нескольких обычных fts сценариях с поиском по отдельным словам:
term QPS:
bleve 1256
blue 2344
fts-engine 3048
and-hl QPS:
bleve 1465
blue 2301
fts-engine 7966
phrase QPS:
bleve 354
blue 169
fts-engine 1301
Особенно удивил результат по фразовому поиску - HAMT тут быстрее в несколько раз. Опустим провал с префиксами - в HAMT там тупо не реализован и висит на костыле из
strings.HasPrefix() ;DBag of words
Отдельно я прогнала индексы по датасетам MS MARCO (спасибо Даниилу за идею) и синтетическим данным: в частности, эти тесты были именно на запросах с поиском по группе слов с оператором OR, иначе говоря - bag-of-words.
На MS MARCO fts почти догнал bleve по качеству:
Recall@k: bleve 0.8666 / fts-engine 0.8589
nDCG@k: bleve 0.7398 / fts-engine 0.7325
MRR: bleve 0.7040 / fts-engine 0.6963
Индекс fts опять заметно меньше, но все еще отстает по скорости:
bleve: 133.8 MB
blue: 66.3 MB
fts-engine: 40.0 MB
QPS: bleve 2984 / fts-engine 863 / blue 179
На синтетических данных
fts вообще дал самые плохие метрики на обоих индексах. То есть можно сделать вывод, что простой OR / bag-of-words поиск пока нельзя назвать сильной стороной fts вообще на любом индексе.Вывод - индексаторы хороши для разных задач.
Radix подходит для префиксного поиска, как автодополнение, тут без новостей. А HAMT не является заменой radix, но быстрее строится и сохраняет хороший QPS на обычных полнотекстовых запросах, причём на бОльшей части сценариев обгоняет
bleve и blue.Имеет смысл даже использовать гибрид - там, где это позволяет структура проекта. Пока
fts выглядит конкурентно по размеру индекса и части классических term запросов, но bag-of-words (ms marco) и качество ранжирования ещё явно требуют доработки.Ps: ниже таблички с бенчами по порядку: radix->hamt. Первый тип бенчей по wiki дампу с разными запросами, второй - на MS MARCO
#fts #projects #perf



