Nous avons une table avec une clé primaire composite composée de trois champs (et c'est dans MySQL 5.1). Il y a près de 200 insertions et 200 sélections par seconde sur cette table, et la taille de la table est d'environ 1 million de lignes et elle augmente.
Ma question est: la "clé primaire composite" diminue-t-elle les performances des insertions et sélections sur cette table?
Dois-je utiliser un simple champ ID INT à augmentation automatique au lieu d'une clé primaire composite? (Je pense que la réponse est très liée à la façon dont MySQL gère les index sur plusieurs colonnes)
INSERT
et UPDATE
les performances varient peu: elles seront quasiment les mêmes pour (INT)
et (INT, INT)
clés.
SELECT
performances du composite PRIMARY KEY
dépend de nombreux facteurs.
Si votre table est InnoDB
, alors la table est implicitement groupée sur le PRIMARY KEY
valeur.
Cela signifie que la recherche des deux valeurs sera plus rapide si les deux valeurs comprennent la clé: aucune recherche de clé supplémentaire ne sera requise.
En supposant que votre requête ressemble à ceci:
SELECT *
FROM mytable
WHERE col1 = @value1
AND col2 = @value2
et la disposition du tableau est la suivante:
CREATE TABLE mytable (
col1 INT NOT NULL,
col2 INT NOT NULL,
data VARCHAR(200) NOT NULL,
PRIMARY KEY pk_mytable (col1, col2)
) ENGINE=InnoDB
, le moteur devra simplement rechercher la valeur de clé exacte dans la table elle-même.
Si vous utilisez un champ d'auto-incrémentation comme faux identifiant:
CREATE TABLE mytable (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
col1 INT NOT NULL,
col2 INT NOT NULL,
data VARCHAR(200) NOT NULL,
UNIQUE KEY ix_mytable_col1_col2 (col1, col2)
) ENGINE=InnoDB
, le moteur devra d'abord rechercher les valeurs de (col1, col2)
dans l'index ix_mytable_col1_col2
, récupérez le pointeur de ligne dans l'index (la valeur de id
) et effectuez une autre recherche par id
dans la table elle-même.
Cependant, pour les tables MyISAM
, cela ne fait aucune différence, car les tables MyISAM
sont organisées en tas et le pointeur de ligne n'est qu'un décalage de fichier.
Dans les deux cas, un même index sera créé (pour PRIMARY KEY
ou pour UNIQUE KEY
) et sera utilisé de la même manière.
S'il s'agit d'InnoDB, la clé primaire composite sera incluse dans chaque entrée de chacun des index secondaires.
Cela signifie que
Ce sont bien sûr respectivement un inconvénient et un avantage.
Les clés primaires composites ne sont pas nécessairement mauvaises, parfois elles peuvent être très utiles car InnoDB les regroupe - ce qui signifie que les analyses de plage (liées au disque) sur le PK peuvent être satisfaites en utilisant beaucoup moins IO opérations que serait requis sur un index non clusterisé.
Bien sûr, si vous avez des clés étrangères dans d'autres tables, elles sont plus larges et doivent inclure la clé entière de votre table principale.
Mais je dirais dans l'ensemble, non. Avoir une clé primaire composite ne pose PAS de problème en soi. Avoir une "grande" clé primaire (par exemple, de gros varchars) peut cependant faire l'affaire, si cela l'emporte sur les avantages du clustering et pouvoir utiliser des index de couverture.
SELECT
s un tout petit peu, bien que l'effet soit à peu près négligeable et ne vaut pas la peine de s'inquiéter.INSERT
s, et vous en faites certainement INSERT
s pour vous en inquiéter. C'est beaucoup plus une préoccupation s'il s'agit d'une table MyISAM, où un INSERT
verrouille la table, que s'il s'agit d'une table InnoDB. Si, en utilisant la clé primaire auto_increment, vous pouviez laisser ces colonnes non indexées, vous bénéficieriez de la modification. Cependant, si vous devez toujours garder ces trois colonnes indexées (par exemple, si vous devez appliquer l'unicité à leur combinaison), cela ne fera rien pour vous en termes de performances.