Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL :index composite fulltext+btree ?

Utiliser IN BOOLEAN MODE .

L'index de date n'est pas utile. Il n'y a aucun moyen de combiner les deux index.

Attention, si un utilisateur recherche quelque chose qui apparaît dans 30 000 lignes, la requête sera lente. Il n'y a pas de solution simple autour d'elle.

Je soupçonne que vous avez un TEXT colonne du tableau ? Si c'est le cas, il y a de l'espoir. Au lieu de faire aveuglément SELECT * , commençons par trouver les identifiants et obtenons le LIMIT appliqué, puis faites le * .

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;

Avec

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

Cette formulation et cette indexation devraient fonctionner comme ceci :

  1. Utilisez FULLTEXT pour trouver 30 000 lignes, fournissez le PK.
  2. Avec le PK, triez 30 000 lignes par date .
  3. Choisissez les 10 derniers, en fournissant date, id
  4. Atteignez la table 10 fois à l'aide du PK.
  5. Trier à nouveau. (Oui, c'est nécessaire.)

Plus (Répondant à une pléthore de commentaires) :

Le but derrière ma reformulation est d'éviter de récupérer tous colonnes de 30K Lignes. Au lieu de cela, il récupère uniquement la PRIMARY KEY , puis le réduit à 10, puis récupère * seulement 10 rangées. Beaucoup moins de choses à pelleter.

Concernant COUNT sur une table InnoDB :

  • INDEX(col) fait en sorte qu'un index l'analyse fonctionne pour SELECT COUNT(*) ou SELECT COUNT(col) sans WHERE .
  • Sans INDEX(col), SELECT COUNT(*)will use the "smallest" index; but SELECT COUNT(col)` aura besoin d'une table scanner.
  • Une analyse de table est habituellement plus lent qu'une analyse d'index.
  • Faites attention au timing :il est considérablement affecté par le fait que l'index et/ou la table sont déjà mis en cache dans la RAM.

Une autre chose à propos de FULLTEXT est le + devant les mots - pour dire que chaque mot doit exister, sinon il n'y a pas de correspondance. Cela peut réduire les 30K.

Le FULLTEXT index fournira la date, id est un ordre aléatoire, pas un ordre PK. Quoi qu'il en soit, il est "erroné" de supposer un ordre quelconque, il est donc "correct" d'ajouter ORDER BY , puis laissez l'optimiseur le lancer s'il sait qu'il est redondant. Et parfois, l'optimiseur peut tirer parti du ORDER BY (pas dans votre cas).

Supprimer uniquement le ORDER BY , dans de nombreux cas, accélère l'exécution d'une requête. En effet, cela évite de récupérer, par exemple, 30 000 lignes et de les trier. Au lieu de cela, il fournit simplement "toutes" 10 lignes.

(Je n'ai aucune expérience avec Postgres, je ne peux donc pas répondre à cette question.)