J'ai une requête du formulaire suivant:
SELECT * FROM MyTable WHERE Timestamp > [SomeTime] AND Timestamp < [SomeOtherTime]
Je voudrais optimiser cette requête et je pense à mettre un index sur l'horodatage, mais je ne sais pas si cela pourrait aider. Idéalement, je voudrais faire de l'horodatage un index clusterisé, mais MySQL ne prend pas en charge les index clusterisés, à l'exception des clés primaires.
MyTable
a plus de 4 millions de lignes.Timestamp
est en fait de type INT
.Timestamp
donné est en moyenne d'environ 20, mais peut atteindre 200.Timestamp
supérieur à la plupart des lignes existantes, mais peut être inférieur à certaines des lignes les plus récentes.Un index sur Timestamp
m'aiderait-il à optimiser cette requête?
Cela ne fait aucun doute. Sans l'index, votre requête doit examiner chaque ligne de la table. Avec l'index, la requête sera à peu près instantanée en ce qui concerne la localisation des bonnes lignes. Le prix que vous paierez est une diminution de performance légère des inserts; mais ce sera vraiment léger.
Vous devez absolument utiliser un index. MySQL n'a aucune idée de l'ordre dans lequel se trouvent ces horodatages, et pour trouver un enregistrement pour un horodatage (ou une plage d'horodatages) donné, il doit parcourir chaque enregistrement. Et avec 4 millions d'entre eux, c'est pas mal de temps! Les index sont votre façon de parler de vos données à MySQL - "Je vais regarder ce champ assez souvent, alors gardez une liste où je peux trouver les enregistrements pour chaque valeur."
Les index en général sont une bonne idée pour les champs régulièrement interrogés. Le seul inconvénient de la définition des index est qu'ils utilisent un espace de stockage supplémentaire, donc à moins que vous ne soyez vraiment à court d'espace, vous devriez essayer de les utiliser. S'ils ne s'appliquent pas, MySQL les ignorera de toute façon.
Si vos requêtes utilisent principalement cet horodatage, vous pouvez tester cette conception (agrandissement de la clé primaire avec l'horodatage en première partie):
CREATE TABLE perf (
, ts INT NOT NULL
, oldPK
, ... other columns
, PRIMARY KEY(ts, oldPK)
, UNIQUE (oldPK)
) ENGINE=InnoDB ;
Cela garantira que les requêtes comme celle que vous avez publiée utiliseront la clé (primaire) en cluster.
L'inconvénient est que vos insertions seront un peu plus lentes. De plus, si vous avez d'autres indices sur la table, ils utiliseront un peu plus d'espace (car ils incluront la clé primaire plus large de 4 octets).
Le plus grand avantage d'un tel index cluster est que les requêtes avec des analyses de grande portée, par exemple les requêtes qui doivent lire de grandes parties de la table ou la table entière trouveront les lignes associées de manière séquentielle et dans l'ordre souhaité (BY timestamp
), qui sera également utile si vous souhaitez regrouper par jour ou semaine ou mois ou année.
L'ancien PK peut toujours être utilisé pour identifier les lignes en gardant une contrainte UNIQUE
dessus.
Vous voudrez peut-être aussi jeter un œil à TokuDB , une variante MySQL (et open source) qui autorise plusieurs index clusterisés .
Je ne suis pas en désaccord avec l'importance de l'indexation pour améliorer les temps de requête sélectionnés, mais si vous pouvez indexer sur d'autres clés (et former vos requêtes avec ces index), la nécessité d'indexer sur l'horodatage peut ne pas être nécessaire.
Par exemple, si vous avez une table avec timestamp
, category
et userId
, il peut être préférable de créer un index sur userId
à la place. Dans un tableau avec de nombreux utilisateurs différents, cela réduira considérablement l'ensemble restant sur lequel rechercher l'horodatage.
... et si je ne me trompe pas, l'avantage serait d'éviter la surcharge de création de l'index d'horodatage à chaque insertion - dans une table avec des taux d'insertion élevés et des horodatages très uniques, cela pourrait être une considération importante.
Je me bats avec les mêmes problèmes d'indexation basés sur les horodatages et autres clés. J'ai encore des tests à faire donc je peux mettre la preuve derrière ce que je dis ici. J'essaierai de poster en fonction de mes résultats.
Un scénario pour une meilleure explication:
catégorie 25% unique
** Je suis désolé, je ne connais pas la surcharge calculée ou l'insertion avec indexation.