Полнотекстовый поиск с InnoDB
Я занимаюсь разработкой веб-приложения большого объема, частью которого является база данных обсуждений MySQL, которую нужно будет плавно увеличить до 20 миллионов строк.
Первоначально я планировал использовать MyISAM для таблиц (для встроенных возможностей полнотекстового поиска), но мысль о блокировке всей таблицы из-за одной операции записи заставляет меня затворяться. Блокировки на уровне строк имеют гораздо больше смысла (не говоря уже о других преимуществах скорости InnoDB при работе с огромными таблицами). Так что по этой причине я довольно решительно настроен использовать InnoDB.
Проблема в том, что... InnoDB не имеет встроенных возможностей полнотекстового поиска.
Стоит ли переходить со сторонней поисковой системы? Как Lucene(C++) / Sphinx? Есть ли у кого-нибудь из ваших ниндзя базы данных какие-либо предложения / рекомендации? Зои LinkedIn (на основе Lucene) выглядит лучшим вариантом на данный момент... будучи построенным на возможностях реального времени (что очень важно для моего приложения). Я немного не решаюсь совершать, но без некоторого понимания...
(К вашему сведению: будет на EC2 с высокопроизводительным оборудованием, использующим PHP для обслуживания внешнего интерфейса)
8 ответов
Я могу ручаться за то, что полный текст MyISAM является плохим вариантом - даже если оставить в стороне различные проблемы с таблицами MyISAM в целом, я видел, как полнотекстовые материалы сходят с рельсов и начинают портить себя и регулярно разрушать MySQL.
Определенно, поисковая система определенно будет самым гибким вариантом: сохраняйте данные постов в MySQL/innodb, а затем экспортируйте текст в свою поисковую систему. Вы можете довольно легко настроить периодическое построение / публикацию полного индекса и добавлять обновления индекса в реальном времени, если вы чувствуете необходимость и хотите тратить время.
Lucene и Sphinx являются хорошими вариантами, как и Xapian, который хорош и легок. Если вы идете по маршруту Lucene, не думайте, что Clucene будет лучше, даже если вы предпочитаете не бороться с Java, хотя я не очень компетентен, чтобы обсуждать плюсы и минусы того или другого.
Наряду с общим отказом от MyISAM, полнотекстовый поиск InnoDB (FTS) наконец-то доступен в выпуске MySQL 5.6.4.
С http://dev.mysql.com/doc/refman/5.6/en/innodb-table-and-index.html:
Эти индексы физически представляются в виде целых таблиц InnoDB, на которые действуют ключевые слова SQL, такие как предложение FULLTEXT оператора CREATE INDEX, синтаксис MATCH() ... AGAINST в операторе SELECT и оператор OPTIMIZE TABLE.
В то время как другие движки обладают множеством различных функций, это InnoDB, поэтому он является родным (что означает, что есть путь обновления), и это делает его достойным вариантом.
Вы должны потратить час и пройти установку и тест-драйв Sphinx и Lucene. Посмотрите, соответствует ли какой-либо из ваших потребностей, в отношении обновлений данных.
Одна из вещей, которая разочаровала меня в Sphinx, это то, что он не очень хорошо поддерживает добавочные вставки. То есть очень дорого переиндексировать после вставки, настолько дорого, что их рекомендуемое решение - разделить ваши данные на более старые, неизменные строки и новые, изменчивые строки. Поэтому каждый поиск, который выполняет ваше приложение, должен был бы выполнять поиск дважды: один раз по большому индексу для старых строк, а также по меньшему индексу для последних строк. Если это не интегрируется с вашими шаблонами использования, этот Sphinx не является хорошим решением (по крайней мере, в его текущей реализации).
Я хотел бы указать на другое возможное решение, которое вы могли бы рассмотреть: пользовательский поиск Google. Если вы можете применить SEO в своем веб-приложении, перенесите функцию индексации и поиска в Google и вставьте текстовое поле поиска Google на свой сайт. Это может быть самый экономичный и масштабируемый способ сделать ваш сайт доступным для поиска.
Возможно, вам не следует так быстро отклонять FT MySQL. Craigslist использовал его.
Скорость MySQL и полнотекстовый поиск позволили craigslist обслуживать своих пользователей. Craigslist использует MySQL для обслуживания примерно 50 миллионов поисковых запросов в месяц со скоростью до 60 поисковых запросов в секунду ".
редактировать
Как прокомментировано ниже, Craigslist, похоже, перешел на Sphinx в начале 2009 года.
Сфинкс, как вы указываете, довольно хорош для этого материала. Вся работа находится в файле конфигурации. Убедитесь, что у вашей таблицы со строками есть какой-то уникальный ключ целочисленного идентификатора, и все будет в порядке.
Попробуй это
ROUND((LENGTH(text) - LENGTH(REPLACE(text, 'serchtext', ''))) / LENGTH('serchtext'),0)!=0
Вы должны взглянуть на Сфинкса. Это стоит попробовать. Он очень быстро индексируется и распространяется. Вам следует взглянуть на этот (http://www.percona.com/webinars/2012-08-22-full-text-search-throwdown) веб-семинар. Это говорит о поиске и имеет некоторые аккуратные ориентиры. Вы можете найти это полезным.
Для тех, кто застрял на более старой версии MySQL / MariaDB (т.е. пользователи CentOS), где InnoDB не поддерживает полнотекстовый поиск, моим решением при использовании таблиц InnoDB было создание отдельной таблицы MyISAM для того, что я хотел найти.
Например, моя основная таблица InnoDB была products
с различными ключами и ссылочной целостностью. Затем я создал простую таблицу MyISAM с именемproduct_search
содержащий два поля, product_id
а также product_name
где последний был установлен на FULLTEXT
индекс. Оба поля фактически являются копией того, что находится в основномproduct
Таблица.
Затем я выполняю поиск в таблице MyISAM, используя полнотекстовый поиск, и выполняю внутреннее присоединение к таблице InnoDB.
Содержимое таблицы MyISAM можно поддерживать в актуальном состоянии с помощью триггеров или модели приложения.
Я бы не рекомендовал это, если у вас есть несколько таблиц, требующих полнотекстового поиска, но для одной таблицы это кажется подходящим решением, пока вы не сможете выполнить обновление.
Если все остальное терпит неудачу, всегда есть soundex_match, который к сожалению не очень точный