Le fait de rendre un champ unique le rend-il indexé?

10

Si je crée une uniquecontrainte sur un champ, dois-je également créer un index sur ce champ afin d'obtenir un temps d'insertion évolutif? Ou est-ce fait pour moi (même si l'index qu'il utilise n'est pas accessible au public?)

Plus précisément, je travaille avec Apache Derby pour le prototypage, bien que je vais probablement le déplacer vers MySQL dans un avenir proche. J'espère également qu'il pourrait y avoir quelque chose dans la norme SQL qui en dit long.

Je n'aurai jamais besoin de chercher par ce champ, donc je préfère ne pas faire d'index inutile. Mais je préfère avoir un index inutile que d'avoir un O(n)temps d'insertion.

corsiKa
la source
2
D'après ce que je sais, une contrainte unique est implémentée derrière l'utilisation d'un index unique. Vous pouvez voir quelques opinions concernant cette situation dans cette question: quand utiliser une contrainte unique au lieu d'un index unique?
Marian
@Marian merci pour ce lien. C'était très perspicace.
corsiKa

Réponses:

2

--ÉDITER--

Ma réponse originale (ci-dessous) ne vous est probablement pas utile du tout car elle ne répond pas à la question des uniquecontraintes. Comme d'autres l'ont dit, ces contraintes sont généralement implémentées avec un index unique implicite. Dans certains cas, cela peut ne pas être vrai (par exemple disable novalidatepour Oracle).

La question pourrait être: est-il possible d'imposer l'unicité sans index? De manière générale, la réponse est non, mais dans certains cas, un index clusterisé signifie que l'index et la table sont le même objet.

--END EDIT--

Vous avez dit "Je préfère avoir un index inutile que d'avoir un temps d'insertion O (n).", Mais en général les bases de données n'ont pas de temps d'insertion O (n). Il y a deux cas à considérer:

  1. Une table normale avec ou sans index:

    Les nouvelles lignes sont vidées en haut du tas. Le SGBDR ne regarde probablement que 1 bloc, donc pas seulement O (1) mais très petit O (1).

    Si la table a des index, un pointeur vers la ligne sera ajouté à chacun. Ce sera généralement une opération O (log (n)).

  2. Une table avec une sorte de clustering en cours, par exemple une table organisée par index ou un cluster pour Oracle, ou un index cluster pour SQL Server et autres:

    De nouvelles lignes sont insérées dans un bloc particulier, ce qui peut entraîner une division ou un débordement du bloc, mais quoi qu'il arrive, il s'agit toujours de O (log (n)) ou mieux , provoqué par l'arborescence b ou une structure similaire utilisée pour trouver le bloc.

Jack dit d'essayer topanswers.xyz
la source
Mais l'unicité sans index serait O(n)comme vous devez vérifier la table entière. Voilà ce que j'essaie d'éviter.
corsiKa
C'est en effet la meilleure réponse à cette question !!! +1
RolandoMySQLDBA
@Trick - oui, j'ai mal compris au début. L'indice est le prix à payer pour la contrainte d'unicité, je le crains. Pouvez-vous utiliser un index clusterisé dans votre cas?
Jack dit d'essayer topanswers.xyz
1
@JackPDougless Je peux utiliser un "index" standard et obtenir un O(lg n)temps d'insertion. Ce n'est pas un problème. Ma question est si le système, sachant que vous avez besoin de cet index pour obtenir un temps d'insertion décent, créerait un index pour moi.
corsiKa
2

CLÉ PRIMAIRE> = UNIQUE> = INDEX == CLÉ

Les données InnoDB sont commandées par le PK. MyISAM PK agit de la même manière qu'UNIQUE.

INSERT doit ajouter une "ligne" à chaque index (de n'importe quel type) que vous avez. Cela prend du temps. (Généralement, le temps n'est pas suffisant pour être important.) Les index sont tous stockés au format BTree. Les blocs MyISAM BTree mesurent 1 Ko; InnoDB utilise 16 Ko.

L'insertion dans InnoDB met à jour le PK et les données simultanément.

L'insertion dans MyISAM "ajoute" généralement les données au .MYD. Séparément, il ajoute une ligne au PK (le cas échéant).

INSERT doit d'abord vérifier qu'il n'y a pas de clé en double pour une clé PRIMARY ou UNIQUE. Cela se fait en utilisant l'index. Et, par conséquent, pourquoi les CONTRAINTES DE CLÉS UNIQUES et ÉTRANGÈRES construisent vraiment des index. C'est O (logN), mais généralement CPU, pas E / S, car si la mise en cache est efficace.

Rick James
la source
Avez-vous une citation dans la spécification InnoDB qui indique qu'une UNIQUEcontrainte créera un index sans que l'utilisateur en spécifie un à faire?
corsiKa
Hmmm ... Non, juste des années d'expérience.
Rick James
Et voici un moyen de le tester ... CRÉER une table sans index secondaire; do SHOW TABLE STATUS - Index_length sera 0. Ensuite, ajoutez un index UNIQUE; L'ETAT DE LA TABLE affichera maintenant quelque chose. (Il se peut que vous deviez mettre une quantité de données non triviale dans le tableau.)
Rick James
1

Pour répondre à la question en gras: Oui, rendre un champ unique l'indexe comme la clé primaire de s. En fait, j'avais discuté de cela dans une autre question concernant les clés primaires ayant leur propre nom pour le distinguer des autres clés uniques (candidates) .

En ce qui concerne les contraintes, des index sont créés pour vous afin que le paradigme des contraintes soit configuré. Vous devriez pouvoir supprimer les index en double, même les clés UNIQUE, tant que la contrainte que vous avez créée ne fait pas référence à d'autres clés UNIQUE que vous avez personnellement créées en dehors du paradigme de contrainte.

Vous n'aurez peut-être jamais à rechercher ce champ, mais MySQL devra certainement le rechercher pour déterminer la validité des clés et déterminer comment effectuer les opérations ON DELETE CASCADE et ON UPDATE CASCADE.

L'index UNIQUE garantit simplement l'unicité des tuples (singletons, paires, triplets, ..., n-tuples, etc.) dans chaque ligne du tableau.

Il est à votre discrétion de supprimer ces index en double, à condition de ne pas briser le paradigme de contrainte que vous souhaitez avoir dans la table.

RolandoMySQLDBA
la source
1
Cela ne répond pas à ma question. Ma question concerne le temps d'insertion. Si vous avez une contrainte unique, le système doit garantir l'unicité du champ avant une insertion - s'il n'y a pas d'index sur le champ, il devra rechercher la table entière ( O(n)). S'il existe un index, la recherche sera beaucoup plus rapide (probablement O(lg n)). Voilà mon problème. Je connais bien la mécanique d'intégrité référentielle, je ne me préoccupe (pour les besoins de cette question) que des performances.
corsiKa