El orden de las columnas tuvo un gran impacto en el rendimiento de algunas de las bases de datos que sintonicé, que abarcan Sql Server, Oracle y MySQL. Esta publicación tiene buenas reglas generales :
- Primero las columnas de clave primaria
- A continuación, columnas de clave externa.
- Columnas buscadas con frecuencia a continuación
- Columnas que se actualizan con frecuencia más adelante
- Las columnas que aceptan valores NULL son las últimas.
- Las columnas que aceptan valores NULL menos utilizadas después de las columnas que aceptan valores NULL utilizadas con más frecuencia
Un ejemplo de diferencia en el rendimiento es una búsqueda de índice. El motor de la base de datos encuentra una fila en función de algunas condiciones del índice y obtiene una dirección de fila. Ahora digamos que está buscando SomeValue, y está en esta tabla:
SomeId int,
SomeString varchar(100),
SomeValue int
El motor tiene que adivinar dónde comienza SomeValue, porque SomeString tiene una longitud desconocida. Sin embargo, si cambia el orden a:
SomeId int,
SomeValue int,
SomeString varchar(100)
Ahora el motor sabe que SomeValue se puede encontrar 4 bytes después del inicio de la fila. Por tanto, el orden de las columnas puede tener un impacto considerable en el rendimiento.
EDITAR: Sql Server 2005 almacena campos de longitud fija al comienzo de la fila. Y cada fila tiene una referencia al inicio de un varchar. Esto niega por completo el efecto que he enumerado anteriormente. Entonces, para las bases de datos recientes, el orden de las columnas ya no tiene ningún impacto.
Actualizar:
En
MySQL
, puede haber una razón para hacer esto.Dado que los tipos de datos variables (como
VARCHAR
) se almacenan con longitudes variables enInnoDB
, el motor de la base de datos debe recorrer todas las columnas anteriores en cada fila para averiguar el desplazamiento de la dada.El impacto puede llegar al 17% para las
20
columnas.Vea esta entrada en mi blog para más detalles:
En
Oracle
, lasNULL
columnas finales no consumen espacio, por eso siempre debe ponerlas al final de la tabla.También en
Oracle
y enSQL Server
, en caso de una fila grande,ROW CHAINING
puede ocurrir un.ROW CHANING
es dividir una fila que no encaja en un bloque y extenderla por varios bloques, conectados con una lista vinculada.La lectura de las columnas finales que no encajan en el primer bloque requerirá recorrer la lista vinculada, lo que resultará en una
I/O
operación adicional .Consulte esta página para ver una ilustración de
ROW CHAINING
enOracle
:Es por eso que debe colocar las columnas que usa a menudo al principio de la tabla y las columnas que no usa a menudo, o las columnas que tienden a serlo
NULL
, al final de la tabla.Nota IMPORTANTE:
Si le gusta esta respuesta y desea votar a favor, vote también a favor de
@Andomar
la respuesta .Él respondió lo mismo, pero parece haber sido rechazado sin ningún motivo.
fuente
Durante la capacitación de Oracle en un trabajo anterior, nuestro DBA sugirió que poner todas las columnas que no aceptan valores NULL antes de las que aceptan valores NULL era ventajoso ... aunque TBH, no recuerdo los detalles de por qué. ¿O tal vez solo los que probablemente se actualizarían deberían ir al final? (Quizás posponga tener que mover la fila si se expande)
En general, no debería haber ninguna diferencia. Como dice, las consultas siempre deben especificar las columnas en sí mismas en lugar de depender del orden de "seleccionar *". No conozco ninguna base de datos que permita cambiarlos ... bueno, no sabía que MySQL lo permitía hasta que lo mencionaste.
fuente
Algunas aplicaciones mal escritas pueden depender del orden / índice de columna en lugar del nombre de columna. No deberían serlo, pero sucede. Cambiar el orden de las columnas rompería tales aplicaciones.
fuente
Legibilidad de la salida cuando tiene que escribir:
select * from <table>
en su software de gestión de bases de datos?
Es una razón muy falsa, pero por el momento no puedo pensar en otra cosa.
fuente
No, el orden de las columnas en una tabla de base de datos SQL es totalmente irrelevante, excepto para fines de visualización / impresión. No tiene sentido reordenar las columnas; la mayoría de los sistemas ni siquiera proporcionan una forma de hacerlo (excepto eliminar la tabla anterior y volver a crearla con el nuevo orden de las columnas).
Bagazo
EDITAR: de la entrada de Wikipedia en la base de datos relacional, aquí está la parte relevante que, para mí, muestra claramente que el orden de las columnas nunca debería ser motivo de preocupación:
Una relación se define como un conjunto de n-tuplas. Tanto en matemáticas como en el modelo de base de datos relacional, un conjunto es una colección desordenada de elementos, aunque algunos DBMS imponen un orden a sus datos. En matemáticas, una tupla tiene un orden y permite la duplicación. EF Codd originalmente definió tuplas usando esta definición matemática. Más tarde, una de las grandes ideas de EF Codd fue que usar nombres de atributos en lugar de un orden sería mucho más conveniente (en general) en un lenguaje informático basado en relaciones. Esta información todavía se utiliza hoy.
fuente
La única razón en la que puedo pensar es para depurar y combatir incendios. Tenemos una tabla cuya columna "nombre" aparece aproximadamente en el décimo lugar de la lista. Es un fastidio cuando hace una selección rápida * de la tabla donde id en (1,2,3) y luego tiene que desplazarse para ver los nombres.
Pero eso es todo.
fuente
Como suele ser el caso, el factor más importante es el siguiente que tiene que trabajar en el sistema. Intento tener las columnas de clave primaria primero, las columnas de clave externa en segundo lugar y luego el resto de las columnas en orden descendente de importancia / significado para el sistema.
fuente
Si va a utilizar mucho UNION, facilitará la comparación de columnas si tiene una convención sobre su ordenación.
fuente
Como se señaló, existen numerosos problemas potenciales de rendimiento. Una vez trabajé en una base de datos en la que poner columnas muy grandes al final mejoraba el rendimiento si no hacía referencia a esas columnas en su consulta. Aparentemente, si un registro abarcaba varios bloques de disco, el motor de la base de datos podría dejar de leer bloques una vez que obtuviera todas las columnas que necesitaba.
Por supuesto, cualquier implicación en el rendimiento depende en gran medida no solo del fabricante que esté utilizando, sino también potencialmente de la versión. Hace unos meses noté que nuestro Postgres no podía usar un índice para una comparación de "me gusta". Es decir, si escribió "alguna columna como 'M%'", no fue lo suficientemente inteligente como para saltar a las M y salir cuando encontró la primera N. Estaba planeando cambiar un montón de consultas para usar "entre". Luego obtuvimos una nueva versión de Postgres y manejó los similares de manera inteligente. Me alegro de no haber podido cambiar las consultas. Obviamente no es directamente relevante aquí, pero mi punto es que cualquier cosa que haga por consideraciones de eficiencia podría quedar obsoleta con la próxima versión.
El orden de las columnas es casi siempre muy relevante para mí porque escribo rutinariamente código genérico que lee el esquema de la base de datos para crear pantallas. Por ejemplo, mis pantallas de "editar un registro" casi siempre se construyen leyendo el esquema para obtener la lista de campos y luego mostrándolos en orden. Si cambiara el orden de las columnas, mi programa seguiría funcionando, pero la visualización podría resultar extraña para el usuario. Por ejemplo, espera ver nombre / dirección / ciudad / estado / código postal, no ciudad / dirección / código postal / nombre / estado. Claro, podría poner el orden de visualización de las columnas en código o en un archivo de control o algo así, pero cada vez que agregamos o elimináramos una columna, tendríamos que recordar actualizar el archivo de control. Me gusta decir las cosas una vez. Además, cuando la pantalla de edición se crea exclusivamente a partir del esquema, agregar una nueva tabla puede significar escribir cero líneas de código para crear una pantalla de edición, lo cual es genial. (Bueno, está bien, en la práctica, por lo general, tengo que agregar una entrada al menú para llamar al programa de edición genérico, y generalmente he renunciado al genérico "seleccione un registro para actualizar" porque hay demasiadas excepciones para que sea práctico .)
fuente
Más allá del ajuste de rendimiento obvio, me encontré con un caso de esquina en el que reordenar las columnas causaba que fallara un script SQL (anteriormente funcional).
De la documentación "Las columnas TIMESTAMP y DATETIME no tienen propiedades automáticas a menos que se especifiquen explícitamente, con esta excepción: de forma predeterminada, la primera columna TIMESTAMP tiene DEFAULT CURRENT_TIMESTAMP y ON UPDATE CURRENT_TIMESTAMP si ninguna de las dos se especifica explícitamente" https: //dev.mysql .com / doc / refman / 5.6 / en / timestamp-initialization.html
Entonces, un comando
ALTER TABLE table_name MODIFY field_name timestamp(6) NOT NULL;
funcionará si ese campo es la primera marca de tiempo (o fecha y hora) en una tabla, pero no de otra manera.Obviamente, puede corregir ese comando alter para incluir un valor predeterminado, pero el hecho de que una consulta que funcionó dejó de funcionar debido a un reordenamiento de columna hizo que me doliera la cabeza.
fuente
La única vez que deberá preocuparse por el orden de las columnas es si su software se basa específicamente en ese orden. Por lo general, esto se debe al hecho de que el desarrollador se volvió vago e hizo un
select *
y luego se refirió a las columnas por índice en lugar de por nombre en su resultado.fuente
En general, lo que sucede en SQL Server cuando cambia el orden de las columnas a través de Management Studio es que crea una tabla temporal con la nueva estructura, mueve los datos a esa estructura desde la tabla anterior, elimina la tabla anterior y cambia el nombre de la nueva. Como puede imaginar, esta es una opción muy pobre para el rendimiento si tiene una mesa grande. No sé si Mi SQL hace lo mismo, pero es una de las razones por las que muchos de nosotros evitamos reordenar las columnas. Dado que select * nunca debe usarse en un sistema de producción, agregar columnas al final no es un problema para un sistema bien diseñado. Por lo general, no se debe alterar el orden de las columnas de la tabla.
fuente
En 2002, Bill Thorsteinson publicó en los foros de Hewlett Packard sus sugerencias para optimizar las consultas de MySQL reordenando las columnas. Desde entonces, su publicación ha sido literalmente copiada y pegada al menos un centenar de veces en Internet, a menudo sin citación. Para citarlo exactamente ...
Fuente: Foros de HP.
¡Pero esa publicación fue hecha en 2002! Este consejo fue para MySQL versión 3.23, más de seis años antes de que se lanzara MySQL 5.1. Y no hay referencias ni citas. Entonces, ¿Bill tenía razón? ¿Y cómo funciona exactamente el motor de almacenamiento a este nivel?
Para citar a Martin Zahn, un profesional certificado por Oracle , en un artículo sobre Los secretos de la migración y encadenamiento de filas de Oracle ...
¡El resto del artículo es una lectura bastante buena! Pero solo estoy citando la parte que es directamente relevante para nuestra pregunta que nos ocupa.
Más de 18 años después, tengo que decirlo: ¡gracias, Bill!
fuente