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

Meilleur moyen de stocker des balises pour la vitesse dans une énorme table

Les index FULLTEXT ne sont vraiment pas aussi rapides que vous ne le pensez.

Utilisez un tableau séparé pour stocker vos balises :

Table tags
----------
id integer PK
tag varchar(20)

Table tag_link
--------------
tag_id integer foreign key references tag(id)
content_id integer foreign key references content(id)
/* this table has a PK consisting of tag_id + content_id */

Table content
--------------
id integer PK
......

Vous SÉLECTIONNEZ tout le contenu avec la balise x en utilisant :

SELECT c.* FROM tags t
INNER JOIN tag_link tl ON (t.id = tl.tag_id)
INNER JOIN content c ON (c.id = tl.content_id)
WHERE tag = 'test'
ORDER BY tl.content_id DESC /*latest content first*/
LIMIT 10;

En raison de la clé étrangère, tous les champs de tag_links sont indexés individuellement.
Le `WHERE tags ='test' sélectionne 1 (!) enregistrement.
Equi-joint ceci avec 10 000 taglinks.
Et Équi-joint qui avec 1 enregistrement de contenu chacun (chaque tag_link ne pointe jamais que sur 1 contenu).
En raison de la limite de 10, MySQL arrête de chercher dès qu'il a 10 éléments, donc il ne regarde vraiment que 10 enregistrements tag_links.
Le content.id est auto-incrémenté, donc des nombres plus élevés sont un proxy très rapide pour les articles plus récents.

Dans ce cas, vous jamais vous devez rechercher autre chose que l'égalité et vous commencez avec 1 balise que vous associez à l'aide de clés entières (la jointure la plus rapide possible).

Il n'y a pas de si-alors-ou-mais à ce sujet, c'est le moyen le plus rapide.

Notez qu'étant donné qu'il n'y a au plus que quelques milliers de balises, toute recherche sera beaucoup plus rapide que de fouiller dans le tableau de contenu complet.

Enfin
Les champs CSV sont une très mauvaise idée, ne les utilisez jamais dans une base de données.