L'ordre des colonnes dans la définition d'une table est-il important?


35

Lors de la définition d'une table, il est utile de classer les colonnes dans les groupes logiques et les groupes eux-mêmes par objectif. L'ordre logique des colonnes dans une table donne un sens au développeur et constitue un élément de bon style.

C'est clair.

Ce qui n'est pas clair, cependant, est de savoir si l'ordre logique des colonnes dans une table a un impact sur leur ordre physique au niveau de la couche de stockage ou s'il a un impact quelconque qui pourrait nous intéresser.

Outre l’impact sur le style, l’ordre des colonnes at-il une importance?

Il y a une question sur Stack Overflow à ce sujet, mais il manque une réponse faisant autorité.

Réponses:


23

L'ordre logique des colonnes dans une table a-t-il un impact sur leur ordre physique au niveau de la couche de stockage? Oui.

Que ce soit important ou non est une question différente à laquelle je ne peux pas (encore) répondre.

D'une manière similaire à celle décrite dans l'article fréquemment lié de Paul Randal sur l' anatomie d'un enregistrement , examinons un simple tableau à deux colonnes avec DBCC IND:

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;

USE master;
GO

IF DATABASEPROPERTY (N'RowStructure', 'Version') > 0 DROP DATABASE RowStructure;
GO

CREATE DATABASE RowStructure;
GO

USE RowStructure;
GO

CREATE TABLE FixedLengthOrder
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
    , c3 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL  
);
GO

INSERT FixedLengthOrder DEFAULT VALUES;
GO

DBCC IND ('RowStructure', 'FixedLengthOrder', 1);
GO

Sortie DBCC IND

La sortie ci-dessus montre que nous devons examiner la page 89:

DBCC TRACEON (3604);
GO
DBCC PAGE ('RowStructure', 1, 89, 3);
GO

Dans la sortie de DBCC PAGE, nous voyons c1 bourré avec le caractère 'A' avant le 'B' de c2:

Memory Dump @0x000000000D25A060

0000000000000000:   10001c00 01000000 41414141 41414141 †........AAAAAAAA
0000000000000010:   41414242 42424242 42424242 030000††††AABBBBBBBBBB...

Et juste parce que, ouvrons RowStructure.mdfun éditeur hexadécimal et confirmons que la chaîne 'A' précède la chaîne 'B':

AAAAAAAAAA

Répétez maintenant le test en inversant l’ordre des chaînes en plaçant les caractères "B" en c1 et les caractères "A" en c2:

CREATE TABLE FixedLengthOrder
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
    , c3 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL  
);
GO

Cette fois, notre sortie DBCC PAGE est différente et la chaîne 'B' apparaît en premier:

Memory Dump @0x000000000FC2A060

0000000000000000:   10001c00 01000000 42424242 42424242 †........BBBBBBBB 
0000000000000010:   42424141 41414141 41414141 030000††††BBAAAAAAAAAA... 

Encore une fois, juste pour rire, vérifions le vidage hexadécimal du fichier de données:

BBBBBBBBBB

Comme l'explique Anatomie d'un enregistrement , les colonnes de longueur fixe et variable d'un enregistrement sont stockées dans des blocs distincts. L'entrelacement logique de types de colonnes fixes et variables n'a aucune incidence sur l'enregistrement physique. Cependant, dans chaque bloc, l'ordre de vos colonnes correspond à l'ordre des octets dans le fichier de données.

CREATE TABLE FixedAndVariableColumns
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
    , c3 VARCHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL  
    , c4 CHAR(10) DEFAULT REPLICATE('C', 10) NOT NULL
    , c5 VARCHAR(10) DEFAULT REPLICATE('D', 10) NOT NULL
    , c6 CHAR(10) DEFAULT REPLICATE('E', 10) NOT NULL  
);
GO

Memory Dump @0x000000000E07C060

0000000000000000:   30002600 01000000 41414141 41414141 0.&.....AAAAAAAA 
0000000000000010:   41414343 43434343 43434343 45454545 AACCCCCCCCCCEEEE 
0000000000000020:   45454545 45450600 00020039 00430042 EEEEEE.....9.C.B 
0000000000000030:   42424242 42424242 42444444 44444444 BBBBBBBBBDDDDDDD 
0000000000000040:   444444†††††††††††††††††††††††††††††††DDD

Voir également:

L'ordre des colonnes n'a pas d'importance… en général, mais - CELA DÉPEND!


+1 je suis d'accord. J'ai toujours constaté qu'au sein de chaque section, l'ordre des colonnes était initialement conforme à celui indiqué dans l' CREATE TABLEinstruction (sauf que les colonnes de clé CI venaient en premier dans la section). Bien que l'ordre des colonnes puisse changer si les ALTER COLUMNtypes de données / la longueur des colonnes sont modifiés . Le seul cas mineur auquel il est important de penser est que les colonnes à la fin de la section de longueur variable avec une chaîne vide ou NULL ne prennent aucun espace dans le tableau de décalage de colonne (démontré par Kalen Delaney dans le livre internals 2008)
Martin Smith

1
L'ordre des colonnes peut avoir de l'importance dans les cas rares. Par exemple, si vous avez une table avec 3 colonnes A, B et C, chacune longue de 3 Ko. Les pages SQL Server ont une taille de 8 Ko et Cne rentrent donc pas dans la page étendue. Donc, à select A, Bpartir de YourTable` ne nécessite que la moitié des lectures de page select A, C from YourTable.
Andomar

"Whether it matters or not is a different issue that I can't answer (yet).": L'ordre des colonnes peut affecter de manière significative les performances. De plus, il peut même avoir un impact sur les erreurs! Vérifiez ceci - La démo 2 le montre mieux, je pense
Ronen Ariely

@RonenAriely Exemple intéressant, mais c'est quelque peu artificiel dans le contexte de la question initiale. Vous montrez comment l'ordre des colonnes a un impact lorsque vous la supprimez par la suite. Je ne pense pas avoir jamais conçu une table avec une vision à l'avance des colonnes que je vais supprimer.
Mark Storey-Smith

Bonjour @ MarkStorey-Smith. (1) En tant qu’architecte, j’explique toujours que la différence entre la conception d’un puits et la conception remarquable est qu’une bonne conception répond aux besoins actuels, tandis que la conception performante répond aux besoins futurs qui ne sont pas encore connus. (2) La réponse à la question est pure OUI. La mise en œuvre de la réponse incombe au PO et à chacun de nous. Cela sort du cadre de la discussion, mais nous pouvons ouvrir ce sujet à la discussion. Mais pas dans la famille des forums stackoverflow, car l’interface ne permet pas d’avoir une vraie discussion mais n’ajoute qu’une mauvaise ligne de texte dans les réponses
Ronen Ariely

7

Si vous ne définissez pas d'index en cluster, vous obtiendrez une table de segment de mémoire. Lors de la lecture de données, vous analyserez toujours les tables entières. Ainsi, l’ensemble des lignes sera lu, ce qui fera de l’ordre des colonnes un point discutable.

Dès que vous définissez un index clusterisé, les données sont physiquement réorganisées pour se conformer à l'ordre physique des colonnes que vous spécifiez - et à ce stade, l'ordre physique devient important. L’ordre physique détermine l’éligibilité de l’opérateur demandeur en fonction des prédicats que vous utilisez.

Bien que je ne me souvienne pas de l'avoir lu n'importe où, je suppose que SQL Server ne garantit pas l'ordre physique des colonnes pour les tas, alors qu'il sera garanti pour les index. Pour répondre à votre question, non, l'ordre des colonnes dans la définition ne devrait pas avoir d'importance, car elles ne le seront pas lors de la lecture des données (notez que cela ne concerne que les tas - les index sont une autre affaire).

Mise à jour
En fait, vous vous posez deux questions: "si le classement logique des colonnes dans une table a un impact sur leur classement physique au niveau de la couche de stockage", la réponse est non. L'ordre logique, tel que défini par les métadonnées, ne doit pas nécessairement être dans le même ordre que l'ordre physique. Si je comprends bien, vous voulez savoir si l’ordre logique de CREATE TABLE produit le même ordre physique lors de la création - ce que je ne connais pas pour les tas - mais avec l’avertissement ci-dessus.


2

D'après ce que j'ai vu et lu, l'ordre des colonnes dans SQL Server ne fait aucune différence. Le moteur de stockage place les colonnes sur la ligne, quelle que soit la manière dont elles sont spécifiées dans l'instruction CREATE TABLE. Cela étant dit, je suis sûr qu'il y a des cas très isolés où cela compte, mais je pense que vous aurez du mal à obtenir une seule réponse définitive à ce sujet. Paul Randal " dans le moteur de stockage"La catégorie blog des articles est la meilleure source pour tous les détails du fonctionnement du moteur de stockage dont je suis au courant. Je pense que vous devriez étudier toutes les différentes manières dont le stockage fonctionne et la matrice qui, dans tous les cas d'utilisation Pour rechercher les cas extrêmes dans lesquels l'ordre aurait une importance. Si un cas particulier n'est pas spécifié et s'applique à ma situation, je commande simplement les colonnes de manière logique sur mon CREATE TABLE. J'espère que cela vous aidera.


1

Je comprends ce que tu veux dire. Du point de vue de la conception, un tableau qui ressemble à ceci:

**EMPLOYEES**
EmployeeID
FirstName
LastName
Birthday
SSN 

est beaucoup mieux qu'une table qui ressemble à ceci:

**EMPLOYEES**
LastName
EmployeeID
SSN 
Birthday
FirstName

Mais le moteur de base de données ne se soucie pas vraiment de votre ordre de colonne logique si vous émettez un tsql comme ceci:

SELECT FirstName, LastName, SSN FROM Employees

Le moteur sait simplement où la liste de FirstName est stockée sur le disque.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.