¿Importa el orden de las columnas en la definición de una tabla?


35

Al definir una tabla, es útil ordenar las columnas en grupos lógicos y los grupos mismos por propósito. El orden lógico de las columnas en una tabla transmite significado al desarrollador y es un elemento de buen estilo.

Eso está claro.

Sin embargo, lo que no está claro es si el orden lógico de las columnas en una tabla tiene algún impacto en su orden físico en la capa de almacenamiento, o si tiene algún otro impacto que pueda interesarle.

Además del impacto en el estilo, ¿importa el orden de las columnas?

Hay una pregunta en Stack Overflow sobre esto, pero carece de una respuesta autorizada.

Respuestas:


23

¿El orden lógico de las columnas en una tabla tiene algún impacto en su orden físico en la capa de almacenamiento? Sí.

Si importa o no es un tema diferente que no puedo responder (todavía).

De manera similar a la descrita en el artículo frecuentemente vinculado de Paul Randal sobre la anatomía de un registro , veamos una tabla simple de dos columnas con 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

Salida DBCC IND

El resultado anterior muestra que debemos mirar la página 89:

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

En la salida de DBCC PAGE vemos c1 relleno con el carácter 'A' antes de 'B' de c2:

Memory Dump @0x000000000D25A060

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

Y solo porque, abra el busto RowStructure.mdfcon un editor hexadecimal y confirme que la cadena 'A' precede a la cadena 'B':

AAAAAAAAAA

Ahora repita la prueba pero invierta el orden de las cadenas, colocando los caracteres 'B' en c1 y los caracteres '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

Esta vez nuestra salida DBCC PAGE es diferente y la cadena 'B' aparece primero:

Memory Dump @0x000000000FC2A060

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

Nuevamente, solo por risitas, verifiquemos el volcado hexadecimal del archivo de datos:

BBBBBBBBBB

Como explica Anatomy of a Record , las columnas de longitud fija y variable de un registro se almacenan en bloques distintos. Lógicamente, el intercalado de tipos de columnas fijas y variables no tiene relación con el registro físico. Sin embargo, dentro de cada bloque, el orden de sus columnas se asigna al orden de bytes en el archivo de datos.

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

Ver también:

El orden de las columnas no importa ... en general, pero ... ¡DEPENDE!


+1 estoy de acuerdo. Siempre he encontrado que, dentro de cada sección, el orden de las columnas inicialmente es según la CREATE TABLEdeclaración (excepto que las columnas de clave CI aparecen primero en la sección). Aunque el orden de las columnas puede cambiar si ALTER COLUMNcambia los tipos de datos / longitudes de columna. El único caso menor en el que importa que se me ocurra es que las columnas al final de la sección de longitud variable con una cadena vacía o NULL no ocupan espacio en absoluto en la matriz de desplazamiento de columnas (demostrado por Kalen Delaney en el libro interno de 2008)
Martin Smith

1
El orden de las columnas puede importar en casos excepcionales de esquina. Por ejemplo, si tiene una tabla con 3 columnas A, B y C, cada una de 3 kb de longitud. Las páginas de SQL Server son de 8 kb, por lo Cque no se ajustan y van a su propia página extendida. Entonces, select A, Bde YourTable` requiere solo la mitad de las lecturas de la página select A, C from YourTable.
Andomar

"Whether it matters or not is a different issue that I can't answer (yet).": El orden de las columnas puede afectar significativamente el rendimiento. Además, ¡incluso puede afectar los errores! Mira esto - La demostración 2 lo muestra mejor, creo
Ronen Ariely

@RonenAriely Ejemplo interesante, pero algo ideado en el contexto de la pregunta original. Estás demostrando cómo el orden de las columnas tiene un impacto cuando posteriormente se cae la columna. No creo que alguna vez haya diseñado una tabla con previsión de las columnas que dejaré caer.
Mark Storey-Smith

Hola @ MarkStorey-Smith. (1) Como arquitecto, siempre explico que la diferencia entre un buen diseño y un Gran diseño es que un buen diseño satisface las necesidades actuales, mientras que el Gran diseño satisface las necesidades futuras que aún no se conocen. (2) La respuesta a la pregunta es SÍ puro. La implementación de la respuesta depende del OP y de cada uno de nosotros. Esto está fuera del alcance de la discusión, pero podemos abrir este tema para discusión. Pero no en la familia de foros stackoverflow, ya que la interfaz no permite tener una discusión real, sino que solo agrega una sola línea corta de texto en las respuestas
Ronen Ariely

7

Si no define un índice agrupado, obtendrá una tabla de montón. Para una tabla de almacenamiento dinámico, siempre estará escaneando al leer datos y, por lo tanto, se leerán las filas completas, lo que hará que el orden de las columnas sea un punto discutible.

Tan pronto como defina un índice agrupado, los datos se reorganizarán físicamente para que se ajusten al orden físico de las columnas según lo especifique, y en este punto, el orden físico se vuelve importante. El orden físico es lo que determina la elegibilidad del operador de búsqueda en función de los predicados que está utilizando.

Si bien no recuerdo haberlo leído en ningún lado, supongo que SQL Server no garantiza el orden físico de las columnas para los montones, mientras que sí estará garantizado para los índices. Para responder a su pregunta, no, el orden de las columnas en la definición no debería importar, ya que no importará al leer los datos (tenga en cuenta que esto es solo para montones: los índices son una cuestión diferente).

Actualización
En realidad, está haciendo dos preguntas: "si el orden lógico de las columnas en una tabla tiene algún impacto en su orden físico en la capa de almacenamiento" es un no. El orden lógico, según lo definido por los metadatos, no tiene que estar en el mismo orden que el físico. Supongo que está buscando una respuesta para saber si el orden lógico en CREAR TABLA da como resultado el mismo orden físico en la creación, que no sé, para montones, aunque con la advertencia anterior.


2

Según lo que he visto y leído, el orden de las columnas en SQL Server no hace ninguna diferencia. El motor de almacenamiento coloca columnas en la fila independientemente de cómo se especifiquen en la instrucción CREATE TABLE. Dicho esto, estoy seguro de que hay algunos casos extremos muy aislados en los que sí importa, pero creo que tendrá dificultades para obtener una respuesta definitiva sobre estos. " El motor de almacenamiento de Paul Randal""La categoría de publicaciones de blog es la mejor fuente para todos los detalles sobre el funcionamiento del motor de almacenamiento que conozco. Creo que tendrías que estudiar todas las diversas formas en que funciona el almacenamiento y la matriz que contra todos los casos de uso para encontrar los casos límite en los que el orden sería importante. A menos que se señale un caso límite específico que se aplique a mi situación, simplemente ordeno las columnas lógicamente en mi CREAR TABLA. Espero que esto ayude.


1

Entiendo lo que dices. Desde la perspectiva del diseño, una tabla que se ve así:

**EMPLOYEES**
EmployeeID
FirstName
LastName
Birthday
SSN 

es mucho mejor que una tabla que se ve así:

**EMPLOYEES**
LastName
EmployeeID
SSN 
Birthday
FirstName

Pero el motor de base de datos realmente no se preocupa por su orden de columna lógica si emite un tsql como este:

SELECT FirstName, LastName, SSN FROM Employees

El motor solo sabe dónde está almacenada la lista de FirstName en el disco.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.