MySQL полнотекстовый поиск и объединения - PullRequest
1 голос
/ 08 сентября 2011

Я создал фото-сайт знаменитостей. После получения 100 000 фотографий мои любительские навыки начали проявляться и нуждаются в быстром оттачивании. Некоторые простые запросы возвращаются за 5-10 секунд!

У меня есть функция поиска в одном текстовом поле, которая будет искать в таблице «фотографии» (заголовок и заголовок), в таблице «люди», в таблице «ключевые слова» и в таблице «photoContributor». Существуют две реляционные / ассоциативные таблицы для "people" и "ключевых слов", называемые photoPeople и photoKeyword.

Один из возможных поисковых запросов пользователя: «Солнцезащитные очки Брэда Питта Анджелины Джоли @MG» - здесь должны быть возвращены все фотографии, которые содержат Брэда и Анджелину вместе, где солнцезащитные очки могут быть просмотрены и сделаны автором @ MG.

Вскоре я понял, что не могу использовать INDEX для моих полей "caption" и "headline" в таблице "photos", потому что я использую предложение "LIKE" с префиксом "%", и что эти конкретные поля установлены в тип данных "LONGTEXT". Поскольку у меня нет индексов для этих полей, это приводит к огромному времени возврата. Поэтому я считаю, что мне нужно использовать поиск «FULLTEXT», затем я могу установить для полей «заголовок» и «заголовок» значение VARCHAR (2000), так как самый большой заголовок на сегодняшний день составляет 1991 символов, и при этом все еще использую «INDEX» особенность, которая, мы надеемся, ускорит процесс. Мне также нравится логическая функция для удаления слов из поиска.

Причина, по которой я пишу этот вопрос, заключается в том, что я совершенно бесполезен в "JOINS". Я, вероятно, могу написать запрос «FULLTEXT» для одной таблицы, и я, возможно, смогу объединить две таблицы, используя левое или правое соединение ... но поскольку у меня есть таблицы ассоциаций / реляционных таблиц, я действительно очень запутался.

Буду признателен, если кто-нибудь представит мне пример запроса с использованием объединений и полнотекстовых данных и реляционных таблиц или просто объяснит мне, какие объединения использовать, если таковые имеются, и любые советы, которые у вас есть для полнотекстового поиска. структура базы данных у меня есть.

Ниже приведена моя базовая схема базы данных:

photos (tbl)
photoID             INT(11)         Primary     Auto-Increment
headline            Long-Text
caption             Long-Text
dateCreated         DateTime

people (tbl)
peopleID            INT(11)         Primary     Auto-Increment
people              VarChar(255)

photoPeople (tbl)
photoID             INT(11)
peopleID            INT(11)

keywords (tbl)
keywordID           INT(11)         Primary     Auto-Increment
keyword             VarChar(255)

photoKeyword (tbl)
photoID             INT(11)
keywordID           INT(11)

photoContributor (tbl)
photoID             INT(11)
contributorRef      VarChar(100)

Когда выполняется поиск, запрашиваемые таблицы / поля: photos.headline, photos.caption, Keywords.keyword, people.people, photoContributor.contributorRef.

Я надеюсь, что кто-нибудь может помочь мне в создании этого срочного запроса.

1 Ответ

2 голосов
/ 08 сентября 2011

Наличие полнотекстового поиска и ограничений внешнего ключа (которые хороши для объединений) - сложная задача для MySQL, поскольку они поддерживаются только механизмами MyISAM и InnoDB соответственно.

Для выполнения полнотекстового поиска вампридется иметь таблицы для движка MyIsam.У меня нет такого большого опыта, поэтому я не могу вам чем-то помочь.

Время, как вы уже догадались, заключается в том, что вы используете префикс%, что вынуждает базу данных просматривать каждую проклятую запись в таблице.перед возвратом.

Если вы хотите использовать объединения, вам придется разделить строку запроса перед опросом базы данных, но это должно быть довольно просто.Хорошее введение в объединения можно найти в руководствах по W3school.http://www.w3schools.com/sql/default.asp

Основная проблема, с которой я могу столкнуться, заключается в следующем: даже если вам удастся реализовать несколько приличных объединений в вашей базе данных, вам все равно придется использовать как в объединенных таблицах (потому что вы не можетесделать полнотекстовый поиск на InnoDB).Из-за этого создание необычных объединений не ускорит ваши запросы.

Мой совет: сделайте больше полей поиска.Это позволит получить что-то хорошее из соединений.Разделите имена людей на Имя, отчество, чтобы избежать необходимости использовать Like.

Если вы действительно хотите сохранить поиск по одному текстовому полю, вам, возможно, придется записать некоторые соглашения о том, как вводить данные (такВы можете разделить его за кулисы и искать), как вы делаете с префиксом для автора.

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

...