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

MySQL:композитен индекс пълен текст+btree?

Използвайте IN BOOLEAN MODE .

Индексът на датите не е полезен. Няма начин да комбинирате двата индекса.

Внимавайте, ако потребител търси нещо, което се показва в 30K реда, заявката ще бъде бавна. Няма директен път около него.

Подозирам, че имате TEXT колона в таблицата? Ако е така, има надежда. Вместо сляпо да правите SELECT * , нека първо намерим идентификаторите и да получим LIMIT приложен, след това направете * .

SELECT a.* 
    FROM tbl AS a
    JOIN ( SELECT date, id
             FROM tbl
             WHERE MATCH(...) AGAINST (...)
             ORDER BY date DESC
             LIMIT 10 ) AS x
        USING(date, id)
    ORDER BY date DESC;

Заедно с

PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)

Тази формулировка и индексиране трябва да работят по следния начин:

  1. Използвайте FULLTEXT за да намерите 30K реда, доставете PK.
  2. С PK сортирайте 30K реда по date .
  3. Изберете последните 10, доставяйки date, id
  4. Върнете се в масата 10 пъти с помощта на ПК.
  5. Сортирайте отново. (Да, това е необходимо.)

Още (В отговор на множество коментари):

Целта зад моето преформулиране е да избегна изтеглянето на всички колони от 30K редове. Вместо това той извлича само PRIMARY KEY , след това намалява това до 10, след което извлича * само 10 реда. Много по-малко неща се изсипват наоколо.

Относно COUNT на таблица на InnoDB:

  • INDEX(col) прави така, че индекс сканирането работи за SELECT COUNT(*) или SELECT COUNT(col) без WHERE .
  • Без INDEX(col), SELECT COUNT(*)will use the "smallest" index; but SELECT COUNT(col)` ще се нуждае от таблица сканиране.
  • Сканирането на таблица е обикновено по-бавно от индексно сканиране.
  • Внимавайте с времето – То се влияе значително от това дали индексът и/или таблицата вече са кеширани в RAM.

Още нещо за FULLTEXT е + пред думи -- да се каже, че всяка дума трябва да съществува, иначе няма съвпадение. Това може да намали 30K.

FULLTEXT index ще предостави date, id е произволен ред, а не PK ред. Както и да е, е „грешно“ да се приема каквато и да е подредба, следователно е „правилно“ да добавите ORDER BY , след което оставете оптимизатора да го хвърли, ако знае че е излишен. И понякога оптимизаторът може да се възползва от ORDER BY (не във вашия случай).

Премахване само на ORDER BY , в много случаи кара заявката да се изпълнява много по-бързо. Това е така, защото избягва извличането, да речем, 30K реда и сортирането им. Вместо това той просто предоставя "всеки" 10 реда.

(Нямам опит с Postgres, така че не мога да отговоря на този въпрос.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Добър дизайн на база данни, променлив брой атрибути

  2. Използване на PHPExcel за създаване на автоматично генерирани excel файлове

  3. ПОРЪЧАЙТЕ ПО дата и час ПРЕДИ ГРУПА ПО име в mysql

  4. Изследване на MySQL Binlog сървър – Ripple

  5. ERROR 1215. MySql InnoDB