Объединив свой опыт и результаты EXPLAIN, кажется, что полнотекстовый индекс не так полезен, как вы ожидаете в данном конкретном случае. Это зависит от конкретных данных в вашей базе данных, от структуры базы данных и / или конкретного запроса.
Обычно движки баз данных используют не более одного индекса на таблицу. Поэтому, когда таблица имеет более одного индекса, оптимизатор запросов пытается использовать лучший. Но оптимизатор не всегда достаточно умен.
Вывод EXPLAIN показывает, что оптимизатор запросов к базе данных решил использовать индексы для relationship
и title
. Фильтр отношений уменьшает таблицу elggentity_relationships
до 6145 строк. И фильтр заголовков уменьшает таблицу elggobjects_entity
до 72697 строк. Затем MySQL необходимо объединить эти таблицы (6145 x 72697 = 446723065 операций фильтрации) без использования какого-либо индекса, поскольку индексы уже использовались для фильтрации. В этом случае это может быть слишком много. MySQL может даже принять решение сохранить промежуточные вычисления на жестком диске, пытаясь сохранить достаточно свободного места в памяти.
Теперь давайте посмотрим на другой запрос. Он использует relationship
и PRIMARY KEY
(из таблицы elggobjects_entity) в качестве своих индексов. Фильтр отношений уменьшает таблицу elggentity_relationships
до 6145 строк. При объединении этих таблиц по индексу PRIMARY KEY
в результате получается только 3957 строк. Это не так много для последнего фильтра (т.е. LIKE "%scelerisque%"
), даже если индекс НЕ используется для этой цели вообще.
Как видите, скорость во многом зависит от индексов, выбранных для запроса. Таким образом, в данном конкретном случае индекс PRIMARY KEY
гораздо полезнее, чем индекс title
с полным текстом, поскольку PRIMARY KEY
оказывает большее влияние на уменьшение результата, чем title
.
MySQL не всегда умен, чтобы установить правильные индексы. Мы можем сделать это вручную, используя такие пункты, как IGNORE INDEX (index_name)
, FORCE INDEX (index_name)
и т. Д.
Но в вашем случае проблема заключается в том, что если мы используем MATCH() AGAINST()
в запросе, тогда требуется полнотекстовый индекс, потому что MATCH() AGAINST()
вообще не работает без полнотекстового индекса. Так что это основная причина, по которой MySQL выбрал неверные индексы для запроса.
UPDATE
ОК, я провел некоторое расследование.
Во-первых, вы можете попытаться заставить MySQL использовать индекс guid_one
вместо relationship
в таблице elggentity_relationships
: USE INDEX (guid_one)
.
Но для еще большей производительности, я думаю, вы можете попытаться создать один индекс для композиции из двух столбцов (guid_one
, membership
). Текущий индекс guid_one
очень похож, но для 3 столбцов, а не для 2. В этом запросе используются только 2 столбца. На мой взгляд, после создания индекса MySQL должен автоматически использовать правильный индекс. Если нет, заставьте MySQL использовать его.
Примечание. После создания индекса не забудьте удалить старую инструкцию USE INDEX
из запроса, поскольку это может помешать запросу использовать вновь созданный индекс. :)