web-dev-qa-db-fra.com

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

Lors de la définition d'une table, il est utile de classer les colonnes en groupes logiques et les groupes eux-mêmes par objectif. L'ordre logique des colonnes dans un tableau transmet du sens au développeur et est 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 autre impact dont on pourrait se soucier.

Mis à part l'impact sur le style, l'ordre des colonnes est-il important?

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

35
Nick Chammas

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 un problème différent auquel je ne peux pas (encore) répondre.

De manière similaire à celle décrite dans l'article fréquemment lié de Paul Randal sur le anatomie d'un enregistrement , regardons 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

DBCC IND output

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

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

Dans la sortie de DBCC PAGE, nous voyons c1 bourré du 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, laisse le buste s'ouvrir RowStructure.mdf avec un éditeur hexadécimal et confirmez que la chaîne 'A' précède la chaîne 'B':

AAAAAAAAAA

Maintenant, répétez le test mais inversez 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 PAGE DBCC 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, permet de vérifier le vidage hexadécimal du fichier de données:

BBBBBBBBBB

Comme Anatomie d'un enregistrement explique, les colonnes de longueur fixe et variable d'un enregistrement sont stockées dans des blocs distincts. L'entrelacement logique des types de colonnes fixes et variables n'a aucune incidence sur l'enregistrement physique. Cependant, à l'intérieur de 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!

23

Si vous ne définissez pas d'index cluster, vous obtiendrez une table de segments. Pour une table de tas, vous analyserez toujours lors de la lecture des données et donc toutes les lignes seront lues, ce qui rend 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 comme vous le spécifiez - et à ce stade, l'ordre physique devient important. L'ordre physique est ce qui détermine l'admissibilité de l'opérateur recherché en fonction des prédicats que vous utilisez.

Bien que je ne me souvienne pas l'avoir lu nulle part, 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 n'auront pas d'importance lors de la lecture des données (notez que c'est seulement pour les tas - les index sont une question différente) .

Mise à jour
En fait, vous posez deux questions - "si l'ordre logique des colonnes dans une table a un impact sur leur ordre physique au niveau de la couche de stockage" est un 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. Je suppose que vous cherchez une réponse à la question de savoir si l'ordre logique dans CREATE TABLE aboutit au même ordre physique à la création - que je ne connais pas, pour les tas - bien qu'avec la mise en garde ci-dessus.

7

Sur la base de ce que j'ai vu et lu, l'ordre des colonnes dans SQL Server ne fait aucune différence. Le moteur de stockage place des colonnes sur la ligne, quelle que soit la façon dont elles sont spécifiées dans l'instruction CREATE TABLE. Cela étant dit, je suis sûr qu'il y a des cas Edge très isolés où cela importe, mais je pense que vous aurez du mal à obtenir une réponse définitive unique à ce sujet. La catégorie de blog " Inside The Storage Engine " de Paul Randal est la meilleure source pour tous les détails sur le fonctionnement du moteur de stockage que je connais. Je pense que vous auriez à étudier toutes les différentes façons dont le stockage fonctionne et à les matricier par rapport à tous les cas d'utilisation pour trouver les cas Edge où l'ordre importerait. À moins qu'un cas Edge spécifique ne soit signalé qui s'applique à ma situation, je commande simplement les colonnes de façon logique sur ma CREATE TABLE. J'espère que ça aide.

2
Todd Everett

Je comprends ce que tu veux dire. Du point de vue de la conception, une table 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 celui-ci:

SELECT FirstName, LastName, SSN FROM Employees

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

1
MarlonRibunal