2016-12-27 1 views
2

Я получил таблицу, как это (я удалил все эти несвязанные поля):MySQL полнотекстовый поиск с Предельное Return Пусто Результаты

CREATE TABLE `products` (
    `id` bigint(20) NOT NULL, 
    `keywords` varchar(2000) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    FULLTEXT KEY `KEYWORDS_FTIDX` (`keywords`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

И есть две строки:

  1. ID: 131072, ключевые слова : product1
  2. ID: 131073, ключевые слова: product2

Если я запускаю запрос SELECT * FROM products WHERE MATCH(keywords) AGAINST('product1' IN BOOLEAN MODE), это Wi Вернем первую строку, как я ожидал.

Но если я добавлю лимит на запрос SELECT * FROM products WHERE MATCH(keywords) AGAINST('product1' IN BOOLEAN MODE) LIMIT 10, то ничего не получил.

Я стараюсь использовать большее количество для LIMIT SELECT * FROM products WHERE MATCH(keywords) AGAINST('product1' IN BOOLEAN MODE) LIMIT 100, он работает снова.

Может кто-нибудь, пожалуйста, дайте мне знать, как это сделать правильно?

+0

Лично со всеми добавленными вами вариантами вы должны опубликовать это в сообществе администраторов баз данных. То есть, если вы понимаете все те дополнения, которые вы добавили к своим операторам T-SQL. Если вы не просто вернете некоторые. – Edward

+0

Я просто запустил mysql в контейнере докера со всеми стандартными конфигурациями для целей разработки. Поэтому я не думаю, что речь идет о вариантах. Но спасибо за советы, я попробую сообщество администраторов баз данных, чтобы узнать, есть ли лучшее решение. – Sean

ответ

0

Я прочитал кое-что о полной реализации индекса текста давно. Речь идет о некоторых из движка индексов, которые просто отмечают удаленные записи как удаленные, а не удаляют их из индекса, и эти удаленные элементы могут пострадать от операции поиска индекса и удаляются из окончательных результатов до того, как они вернутся к пользователю.

Так что если mysql работает таким образом, то я использую LIMIT с MATCH, mysql может просто искать начало индекса для лучшей производительности. Но все эти строки уже удалены, поэтому я получил пустой результат.

Тогда я сделал те и результат доказал:

  1. создать тестовую таблицу использовать точно такой же запрос я отправил в вопросе части.
  2. Вставить две строки: id: 1, keywords: product1, id: 2, keywords: product2.
  3. Запустить поисковый запрос: SELECT * FROM products WHERE MATCH(keywords) AGAINST('product1' IN BOOLEAN MODE) LIMIT 1, после чего я получил правильный результат.
  4. Удалите все эти две записи и вставьте их снова.
  5. Запустите запрос с шага 3, затем ничего не получил.
  6. Но если я запустил: SELECT * FROM products WHERE MATCH(keywords) AGAINST('product1' IN BOOLEAN MODE) LIMIT 2, он снова вернет правильный результат.

Так что на данный момент быстрое исправление может сочетать условие соответствия с другим. В этом случае mysql будет извлекать больше, чем просто нужно в фазе соответствия. И этот запрос работает: SELECT * FROM products WHERE MATCH(keywords) AGAINST('product1' IN BOOLEAN MODE) AND id >= 0 LIMIT 1

Я также использовал объяснение по запросу, он также использовал индекс KEYWORDS_FTIDX.

Эти строки из MySQL Doc (https://dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html) может также о проблеме:

Удаление записи, которая имеет индекс столбца полнотекстового может привести многочисленные небольшие делеции в вспомогательных таблицах индексных, что делает одновременный доступ к этим таблицы - точка раздора. Чтобы избежать этой проблемы, идентификатор документа (DOC_ID) удаленного документа регистрируется в специальной таблице FTS_ _DELETED всякий раз, когда запись удаляется из индексированной таблицы, а индексированная запись остается в полнотекстовом индексе.Перед возвратом результатов запроса информация в таблице FTS_ _DELETED используется для фильтрации удаленных идентификаторов документов. Преимущество этого дизайна в том, что удаление происходит быстро и недорого. Недостатком является то, что размер индекса сразу не уменьшается после удаления записей. Чтобы удалить полнотекстовые записи индекса для удаленных записей, вы должны запустить OPTIMIZE TABLE в индексированной таблице с innodb_optimize_fulltext_only = ON, чтобы перестроить полнотекстовый индекс. Дополнительные сведения см. В разделе Оптимизация полнотекстовых индексов InnoDB.

Смежные вопросы