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 :
- Utilisez
FULLTEXT
pour trouver 30 000 lignes, fournissez le PK. - Avec le PK, triez 30 000 lignes par
date
. - Choisissez les 10 derniers, en fournissant
date, id
- Atteignez la table 10 fois à l'aide du PK.
- 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(*)
ouSELECT COUNT(col)
sansWHERE
. - 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.)