Mysql
 sql >> база данни >  >> RDS >> Mysql

Съставен FULLTEXT индекс в MySQL

Отговорът на @Alden Quimby е правилен, доколкото се отнася, но има още нещо в историята, защото MySQL само опитва да избере оптималния индекс и способността му да направи това определяне е ограничена поради начина, по който пълнотекстовите индекси взаимодействат с оптимизатора.

Това, което всъщност се случва е следното:

Ако посоченият user_id съществува в 0 или 1 съвпадащи редове в таблицата, оптимизаторът ще осъзнае това и ще избере user_id като индекс за тази заявка. Бързо изпълнение.

В противен случай оптимизаторът ще избере пълнотекстовия индекс, като филтрира всеки ред, съответстващ на пълнотекстовия индекс, за да елиминира редове, които не съдържат user_id, който съответства на клаузата WHERE. Не толкова бързо.

Така че това не е наистина "оптималния" път. По-скоро е пълен текст, с добра оптимизация за избягване на пълнотекстово търсене при едно условие, че знаем, че нямаме почти нищо интересно в таблицата.

Причината за това да се развали е, че пълнотекстовият индекс не дава никаква значима статистика обратно на оптимизатора. Просто се казва "да, мисля, че заявката вероятно трябва да изисква от мен да проверя само 1 ред" ... което, разбира се, много радва оптимизатора, така че пълнотекстовият индекс печели офертата за най-ниска цена, освен ако индексът с цяло число стойността също е сравнително ниска или по-ниска.

Все пак това не означава, че не бих го опитал първо по този начин.

Има и друга опция, която би работила най-добре с пълнотекстови заявки IN BOOLEAN MODE а това е да създадете друга колона, която да попълните с нещо като CONCAT('user_id_',user_id) или нещо подобно, и след това да декларирате пълнотекстов индекс с 2 колони.

filter_string VARCHAR(48) # populated with CONCAT('user_id_',user_id);
....
FULLTEXT KEY (message,filter_string)

След това посочете всичко в заявката.

SELECT ...
 WHERE user_id = 500 AND
 MATCH (message,filter_string) AGAINST ('+kittens +puppies +user_id_500' IN BOOLEAN MODE);

Сега пълнотекстовият индекс ще отговаря за съпоставянето само на онези редове, където котета, кученца и "user_id_500" се появяват в комбинирания пълнотекстов индекс на двете колони, но все пак бихте искали да имате и целочисления филтър там, за да сте сигурни, че крайните резултати са ограничени, въпреки произволното появяване на "user_id_500" в съобщението.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL заявка заседнала в състояние на статистиката

  2. Как да копирам данни от една таблица в друга нова таблица в MySQL?

  3. SQL:избиране на редове, където стойността на колоната е променена от предишния ред

  4. Изберете всички дублиращи се редове въз основа на една или две колони?

  5. Получаване на всички записи от MySQL база данни, които са в Google Maps .getBounds?