Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > Эффективный поиск %подстроки% в строке


Автор: afiskon 27.6.2011, 12:06
Помогите, пожалуйста, со следующей задачей.

Есть таблица, содержащая несколько миллионов строк, длина которых колеблется где-то в диапазоне от 1 до 70-и. Нужно быстро находить строки по %подстроке%. В качестве БД можно использовать MySQL или PostgreSQL.

В документации к MySQL сказано:
Цитата

If you use ... LIKE '%string%' and string is longer than three characters, MySQL uses the http://en.wikipedia.org/wiki/Boyer-Moore_algorithm#Variants algorithm to initialize the pattern for the string and then uses this pattern to perform the search more quickly.


Похоже, это не оптимальный вариант, так что простой индекс не годится. Обнаружил, что в MySQL есть поддержка FULLTEXT индекса:

Цитата

You can also create FULLTEXT indexes. These are used for full-text searches. Only the MyISAM storage engine supports FULLTEXT indexes and only for CHAR, VARCHAR, and TEXT columns. Indexing always takes place over the entire column and column prefix indexing is not supported. 


И вроде они даже работают http://habrahabr.ru/blogs/mysql/25646/. Смущает только упоминание морфологии и стоп-слов. Это ведь можно отключить?

В PostgreSQL FULLTEXT индексов не нашел. Может, плохо искал?

Еще, как вариант, в обоих СУБД можно сделать таблицу, содержащую наши строки, сдвинутые (не цеклически) на 1, 2, 3 и тд символов влево с простым индексом. Такая штука должна быстро решать задачу, но смущает сложность реализации-поддержки. Хотелось бы использовать встроенные средства СУБД.

Что посоветуете?

Автор: LSD 27.6.2011, 13:31
Цитата(afiskon @  27.6.2011,  13:06 Найти цитируемый пост)
Это ведь можно отключить?

Нужно учитывать, что полнотекстовый поиск не полностью эквивалентен LIKE.


Цитата(afiskon @  27.6.2011,  13:06 Найти цитируемый пост)
В PostgreSQL FULLTEXT индексов не нашел. Может, плохо искал?

http://www.postgresql.org/docs/8.3/static/textsearch.html

Автор: afiskon 27.6.2011, 13:39
Спасибо за ссылку.

Цитата

Цитата(afiskon @  27.6.2011,  13:06 Найти цитируемый пост)
Это ведь можно отключить?

Нужно учитывать, что полнотекстовый поиск не полностью эквивалентен LIKE.


Да, почитал. Поиск по релевантности. Совсем не то.

Выходи, единственное решение - дополнительная таблица? Даже в PostgreSQL ничего на мой случай не предусмотрено?

Автор: LSD 27.6.2011, 13:48
Цитата(afiskon @  27.6.2011,  14:39 Найти цитируемый пост)
Да, почитал. Поиск по релевантности. Совсем не то.

Там есть IN BOOLEAN MODE, который не учитывает релевантность, а только вхождение слова в индекс. Но я имел в виду, что полнотекстовый поиск ищет только по словам. Т.е. знаки препинание, пробелы и т.д. в индексе отсутствуют.

P.S. http://mysql.ru/docs/man/Fulltext_Fine-tuning.html.

Автор: Akina 27.6.2011, 13:51
Цитата(afiskon @  27.6.2011,  14:39 Найти цитируемый пост)
Да, почитал. Поиск по релевантности. Совсем не то.

Плохо читал. Читай ещё раз, но ВНИМАТЕЛЬНО.
Цитата(LSD @  27.6.2011,  14:31 Найти цитируемый пост)
полнотекстовый поиск не полностью эквивалентен LIKE

Зависит от режима и модификаторов. Можно сделать полностью эквивалентным.

Добавлено через 41 секунду
Цитата(LSD @  27.6.2011,  14:48 Найти цитируемый пост)
я имел в виду, что полнотекстовый поиск ищет только по словам. Т.е. знаки препинание, пробелы и т.д. в индексе отсутствуют.

ааа... это верно.

Автор: afiskon 27.6.2011, 13:55
Для латиницы, цифр и тире (которое можно заменить на подчеркивание или другой знак) полнотекстовый поиск подойдет? Извините за глупые вопросы, но я действительно не знаток БД.

Автор: Akina 27.6.2011, 13:55
Цитата(afiskon @  27.6.2011,  13:06 Найти цитируемый пост)
Такая штука должна быстро решать задачу, но смущает сложность реализации-поддержки

Ну в принципе на базе триггеров несложно реализовать доп. таблицу таких "повёрнутых" строк... но её размер... и тормоза на операциях изменения данных...

Автор: afiskon 27.6.2011, 13:57
Данные, к счатью, не изменяются. Но добавляются новые.

Автор: Akina 27.6.2011, 13:59
ааа... ну тогда действительно один раз создать индексированную таблицу версий подстрок и быстро искать по индексу. Ну будет у тебя в этой таблице сотня миллионов строк... хотя всё равно получится не сказать что очень быстро.

Автор: afiskon 27.6.2011, 14:01
Видимо, нужно тупо экспериментировать. Спасибо за помощь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)