web-dev-qa-db-fra.com

Y a-t-il une raison de s'inquiéter de l'ordre des colonnes dans un tableau?

Je sais que vous pouvez modifier l'ordre des colonnes dans MySQL avec FIRST et AFTER, mais pourquoi voudriez-vous vous déranger? Etant donné que les bonnes requêtes nomment explicitement les colonnes lors de l'insertion de données, existe-t-il vraiment une raison de se soucier de l'ordre dans lequel vos colonnes se trouvent dans la table? 

74
lynn

L'ordre des colonnes a eu un impact important sur les performances de certaines des bases de données que j'ai optimisées, couvrant SQL Server, Oracle et MySQL. Cet article a bonnes règles de base :

  • Colonnes de clé primaire en premier
  • Colonnes de clé étrangère ensuite. 
  • Colonnes fréquemment recherchées ensuite
  • Colonnes fréquemment mises à jour plus tard
  • Les colonnes nullables en dernier. 
  • Les colonnes nullables les moins utilisées après les colonnes nullables les plus fréquemment utilisées

Un exemple de différence de performances est une recherche d'index. Le moteur de base de données trouve une ligne en fonction de certaines conditions de l'index et récupère une adresse de ligne. Maintenant, supposons que vous cherchiez SomeValue, et que ce soit dans ce tableau:

 SomeId int,
 SomeString varchar(100),
 SomeValue int

Le moteur doit deviner où SomeValue démarre, car SomeString a une longueur inconnue. Cependant, si vous modifiez l'ordre en:

 SomeId int,
 SomeValue int,
 SomeString varchar(100)

Le moteur sait maintenant que SomeValue peut être trouvé 4 octets après le début de la ligne. L'ordre des colonnes peut donc avoir un impact considérable sur les performances.

EDIT: SQL Server 2005 stocke les champs de longueur fixe au début de la ligne. Et chaque ligne a une référence au début d'un varchar. Cela annule complètement l'effet que j'ai énuméré ci-dessus. Ainsi, pour les bases de données récentes, l'ordre des colonnes n'a plus d'impact.

86
Andomar

Mettre à jour:

Dans MySQL, il peut y avoir une raison de le faire.

Etant donné que les types de données variables (tels que VARCHAR) sont stockés avec des longueurs variables dans InnoDB, le moteur de base de données doit parcourir toutes les colonnes précédentes de chaque ligne pour connaître le décalage de celle donnée.

L'impact peut être aussi important que 17% pour les colonnes 20.

Voir cette entrée dans mon blog pour plus de détails:

Dans Oracle, les dernières colonnes NULL ne consomment pas d’espace, c’est pourquoi vous devriez toujours les mettre à la fin de la table.

De même dans Oracle et dans SQL Server, dans le cas d'une grande ligne, un ROW CHAINING peut se produire.

ROW CHANING est en train de scinder une ligne qui ne rentre pas dans un bloc et de l'étendre sur plusieurs blocs, connectés à une liste liée.

La lecture des colonnes de fin qui ne rentrent pas dans le premier bloc nécessitera de parcourir la liste des liens, ce qui entraînera une opération I/O supplémentaire.

Voir cette page pour une illustration de ROW CHAINING dans Oracle:

C'est pourquoi vous devriez mettre les colonnes que vous utilisez souvent au début de la table, et les colonnes que vous n'utilisez pas souvent, ou les colonnes qui ont tendance à être NULL, à la fin de la table.

Note importante:

Si vous aimez cette réponse et souhaitez voter pour elle, veuillez également voter pour la réponse de @Andomar .

Il a répondu à la même chose, mais semble avoir été voté sans raison.

37
Quassnoi

Lors de la formation Oracle à un emploi précédent, notre administrateur de base de données a suggéré qu'il était avantageux de placer toutes les colonnes non nullables avant celles non nullables ... bien que TBH je ne me souvienne pas des détails de pourquoi. Ou peut-être était-ce seulement ceux qui étaient susceptibles d'être mis à jour devraient aller à la fin? (Peut-être évite d'avoir à déplacer la ligne si elle se développe)

En général, cela ne devrait faire aucune différence. Comme vous le dites, les requêtes doivent toujours spécifier les colonnes elles-mêmes plutôt que de s'appuyer sur l'ordre de "select *". Je ne connais aucune base de données qui permette de les modifier ... eh bien, je ne savais pas que MySQL le permettait jusqu'à ce que vous le mentionniez.

6
araqnid

Non, l'ordre des colonnes dans une table de base de données SQL n'a aucune importance, sauf pour l'affichage ou l'impression. Il est inutile de réorganiser les colonnes - la plupart des systèmes ne fournissent même pas un moyen de le faire (à l'exception de supprimer l'ancienne table et de la recréer avec le nouvel ordre des colonnes).

Marc

EDIT: extrait de l'entrée Wikipedia sur la base de données relationnelle, voici la partie pertinente qui me montre clairement que l'ordre des colonnes ne devrait jamais être préoccupant:

Une relation est définie comme un ensemble de n-tuples. En mathématiques et dans le modèle de base de données relationnelle, un ensemble est une collection non ordonnée , bien que certains SGBD imposent un ordre à leurs données. En mathématiques, un tuple a un ordre et permet la duplication. E.F. Codd a défini à l'origine les tuples en utilisant cette définition mathématique. Plus tard, c’est l’une des grandes idées de E.F. Codd selon laquelle l’utilisation de noms d’attributs au lieu d’un ordre serait beaucoup plus pratique (en général) dans un langage informatique basé sur des relations. Cette idée est encore utilisée aujourd'hui. 

5
marc_s

Certaines applications mal écrites peuvent dépendre de l'ordre/de l'index des colonnes au lieu du nom de la colonne. Ils ne devraient pas l'être, mais cela arrive. Changer l'ordre des colonnes casserait de telles applications.

5
Craig Walker

Lisibilité de la sortie lorsque vous devez taper:

select * from <table>

dans votre logiciel de gestion de base de données?

C'est une raison très fausse, mais pour le moment, je ne peux penser à rien d'autre.

4
ChrisF

La seule raison pour laquelle je peux penser est pour le débogage et la lutte contre les incendies. Nous avons une table dont la colonne "name" apparaît environ 10 dans la liste. Il est difficile de sélectionner rapidement * dans le tableau où id (1,2,3), puis de faire défiler les noms.

Mais c'est à peu près tout.

2
Chris Simpson

Au-delà de l'optimisation évidente des performances, je viens de rencontrer un cas de figure dans lequel la réorganisation des colonnes entraînait l'échec d'un script SQL (auparavant fonctionnel). 

Dans la documentation "TIMESTAMP et DATETIME n'ont pas de propriétés automatiques à moins d'être spécifiées explicitement, avec cette exception: Par défaut, la première colonne TIMESTAMP a à la fois DEFAULT CURRENT_TIMESTAMP et ON UPDATE CURRENT_TIMESTAMP si aucune n'est spécifiée explicitement" https: // dev .mysql.com/doc/refman/5.6/fr/timestamp-initialization.html

Ainsi, une commande ALTER TABLE table_name MODIFY field_name timestamp(6) NOT NULL; fonctionnera si ce champ est le premier horodatage (ou date/heure) d'une table, mais pas autrement. 

Évidemment, vous pouvez corriger cette commande alter pour inclure une valeur par défaut, mais le fait qu’une requête qui a fonctionné a cessé de fonctionner en raison d’une réorganisation des colonnes m'a fait mal à la tête. 

1
slacker525600

Comme c'est souvent le cas, le facteur le plus important est le prochain type qui doit travailler sur le système. J'essaie de commencer par les colonnes de clé primaire, les colonnes de clé étrangère en second, puis le reste des colonnes par ordre décroissant d'importance pour le système.

1
James L

Si vous allez beaucoup utiliser UNION, cela facilite la correspondance des colonnes si vous avez une convention concernant leur classement.

1
Allain Lalonde

La seule fois où vous aurez à vous soucier de l'ordre des colonnes, c'est si votre logiciel repose spécifiquement sur cet ordre. Cela est généralement dû au fait que le développeur est devenu paresseux et a effectué un select *, puis a fait référence aux colonnes par index plutôt que par nom dans leurs résultats.

0
Soviut

En général, dans SQL Server, lorsque vous modifiez l'ordre des colonnes dans Management Studio, il crée une table temporaire avec la nouvelle structure, déplace les données de cette table à cette structure, supprime l'ancienne table et renomme la nouvelle. Comme vous pouvez l’imaginer, c’est un très mauvais choix en termes de performances si vous avez une grande table. Je ne sais pas si My SQL fait de même, mais c'est l'une des raisons pour lesquelles nombre d'entre nous évitent de réorganiser les colonnes. Etant donné que select * ne doit jamais être utilisé dans un système de production, l’ajout de colonnes à la fin n’est pas un problème pour un système bien conçu. L'ordre des colonnes dans la table ne doit généralement pas être modifié.

0
HLGEM

Comme indiqué, il existe de nombreux problèmes de performances potentiels. Une fois, j'ai travaillé sur une base de données où la mise à la fin de très grandes colonnes améliorait les performances si vous ne référenciez pas ces colonnes dans votre requête. Apparemment, si un enregistrement couvrait plusieurs blocs de disque, le moteur de base de données pourrait arrêter de lire les blocs dès qu'il disposerait de toutes les colonnes nécessaires.

Bien entendu, toutes les implications en termes de performances dépendent fortement non seulement du fabricant que vous utilisez, mais aussi potentiellement de la version. Il y a quelques mois, j'ai remarqué que notre Postgres ne pouvait pas utiliser d'index pour une comparaison "similaire". Autrement dit, si vous écriviez "une colonne telle que" M% "", il n’était pas assez intelligent pour passer aux M et s’arrêter quand il a trouvé le premier N. Je prévoyais de modifier un ensemble de requêtes en utilisant "entre". Ensuite, nous avons eu une nouvelle version de Postgres qui s’est bien comporté. Heureux de ne jamais avoir eu le temps de changer les requêtes. Évidemment, ce n’est pas directement pertinent ici, mais j’essaie de dire que tout ce que vous ferez pour des raisons d’efficacité pourrait être obsolète avec la prochaine version.

L'ordre des colonnes est presque toujours très pertinent pour moi, car j'écris régulièrement du code générique qui lit le schéma de base de données pour créer des écrans. Par exemple, mes écrans "Editer un enregistrement" sont presque toujours construits en lisant le schéma pour obtenir la liste des champs, puis en les affichant dans l'ordre. Si je changeais l'ordre des colonnes, mon programme fonctionnerait toujours, mais l'affichage pourrait être étrange pour l'utilisateur. Par exemple, vous vous attendez à voir nom/adresse/ville/état/code postal, et non ville/adresse/code postal/nom/état. Bien sûr, je pourrais mettre l’ordre d’affichage des colonnes dans du code, un fichier de contrôle ou quelque chose du genre, mais chaque fois que nous ajoutions ou supprimions une colonne, nous devions penser à mettre à jour le fichier de contrôle. J'aime dire des choses une fois. En outre, lorsque l'écran d'édition est construit uniquement à partir du schéma, l'ajout d'un nouveau tableau peut signifier l'écriture de zéro ligne de code pour créer un écran d'édition, ce qui est vraiment cool. (Bon, d'accord, en pratique, je dois généralement ajouter une entrée au menu pour appeler le programme d'édition générique, et j'ai généralement renoncé à l'utilisation générique de "sélectionner un enregistrement à mettre à jour" car il y a trop d'exceptions pour le rendre pratique. .)

0
Jay