example - tinyint mysql
¿Cuál es más rápido: char(1) o tinyint(1)? ¿Por qué? (8)
MI PLATAFORMA:
PHP y mySQL
MI SITUACIÓN:
Me encontré con una situación en la que necesito almacenar un valor para la selección del usuario en una de mis columnas de una tabla. Ahora mis opciones serían:
- O declara la columna como char (1) y almacena el valor como ''y'' o ''n''
- O declare la columna como tinyint (1) y almacene el valor como 1 o 0
- Esta columna así declarada, también puede ser indexada para su uso dentro de la aplicación.
MIS PREGUNTAS:
Entonces, quería saber cuál de los dos tipos anteriores:
Conduce a una velocidad de consulta más rápida cuando se accede a esa columna (en aras de la simplicidad, dejemos de mezclar otras consultas o acceder a otras columnas, por favor).
¿Es la forma más eficiente de almacenar y acceder a los datos y por qué?
¿Cómo varía la velocidad de acceso si las columnas están indexadas y cuándo no?
Según tengo entendido, dado que char (1) y tinyint (1) ocupan solo 1 byte de espacio, el espacio de almacenamiento no será un problema en este caso. Entonces, lo que quedará es la velocidad de acceso. Hasta donde yo sé, la indexación numérica es más rápida y más eficiente que cualquier otra cosa. Pero el caso aquí es difícil de decidir, creo. Definitivamente me gustaría escuchar tu experiencia en este.
Gracias de antemano.
Ambos van a estar tan cerca que no importa. Si sientes que tienes que hacer esta pregunta en SO, estás sobre-optimizando. Use el que tenga el sentido más lógico.
Aunque mi corazonada es que un índice en un TINYINT sería más rápido que un índice en un CHAR (1) debido al hecho de que no hay una sobrecarga de manejo de cadenas (intercalación, espacios en blanco, etc.), no tengo ningún hecho para respalda esto. Supongo que no hay una diferencia de rendimiento significativa por la que valga la pena preocuparse.
Sin embargo, debido a que está usando PHP, almacenarlo como TINYINT tiene mucho más sentido. Usar los valores 1/0 es equivalente a usar true
y false
, incluso cuando se devuelven como cadenas a PHP, y se pueden manejar como tales. Simplemente puede hacer un if ($record[''field''])
con sus resultados como una verificación booleana, en lugar de convertir entre ''y'' y ''n'' todo el tiempo.
Creo que deberías crear una columna con ENUM(''n'',''y'')
. Mysql almacena este tipo de manera óptima. También lo ayudará a almacenar solo los valores permitidos en el campo.
También puedes hacer que ENUM(''no'',''yes'')
sea más amigable para los humanos sin afectar el rendimiento. Porque las cadenas ''no''
y ''yes''
se almacenan solo una vez por definición ENUM
. Mysql almacena solo el índice del valor por fila.
También tenga en cuenta acerca de la clasificación por columna ENUM
:
Los valores ENUM se ordenan de acuerdo con el orden en que se enumeraron los miembros de la enumeración en la especificación de la columna. (En otras palabras, los valores ENUM se ordenan según sus números índices). Por ejemplo, ''a'' ordena antes que ''b'' para ENUM (''a'', ''b''), pero ''b'' ordena antes de ''a'' para ENUM (''b'', ''a'').
Para saberlo con certeza, debe compararlo. O sepa que probablemente no importe tanto en la vista más grandiosa de todo el proyecto.
Las columnas de caracteres tienen codificaciones y colaciones, y compararlas podría implicar cambios innecesarios entre codificaciones, así que supongo que una int será más rápida. Por el mismo motivo, creo que actualizar un índice en una columna int también es más rápido. Pero, de nuevo, no importará mucho.
CHAR
puede ocupar más de un byte, dependiendo del conjunto de caracteres y las opciones de tabla que elijas. Algunos caracteres pueden tomar tres bytes para codificar, por lo que MySQL a veces reserva ese espacio, incluso si solo usa y
y n
.
Si especifica los tipos BOOL
o BOOLEAN
como un tipo de columna al crear una tabla en MySQL, crea el tipo de columna como TINYINT(1)
. Presumiblemente, este es el más rápido de los dos.
También:
Pretendemos implementar un manejo de tipo booleano completo, de acuerdo con SQL estándar, en una futura versión de MySQL.
Usar tinyint es una práctica más estándar, y le permitirá verificar más fácilmente el valor del campo.
// Using tinyint 0 and 1, you can do this:
if($row[''admin'']) {
// user is admin
}
// Using char y and n, you will have to do this:
if($row[''admin''] == ''y'') {
// user is admin
}
No soy un experto en el funcionamiento interno de MySQL, pero intuitivamente siento que recuperar y clasificar campos enteros es más rápido que los campos de caracteres (me da la sensación de que ''a''> ''z'' es más trabajo que 0> 1) , y parece sentirse mucho más familiar desde una perspectiva informática en la que los 0 y los 1 son los indicadores estándar de encendido / apagado. Por lo tanto, el almacenamiento de los enteros parece ser mejor, se siente mejor y es más fácil de usar en la lógica del código. 0/1 es el claro ganador para mí.
También puede observar que, hasta cierto punto, esta es la posición oficial de MySQL, también, de su documentación :
BOOL, BOOLEAN: Estos tipos son sinónimos de TINYINT (1). Un valor de cero se considera falso. Los valores distintos de cero se consideran verdaderos.
Si MySQL llega a igualar TINYINT (1) con BOOLEAN, parece que es el camino a seguir.
Rate insert tinyint(1) insert char(1) insert enum(''y'', ''n'')
insert tinyint(1) 207/s -- -1% -20%
insert char(1) 210/s 1% -- -19%
insert enum(''y'', ''n'') 259/s 25% 23% --
Rate insert char(1) insert tinyint(1) insert enum(''y'', ''n'')
insert char(1) 221/s -- -1% -13%
insert tinyint(1) 222/s 1% -- -13%
insert enum(''y'', ''n'') 254/s 15% 14% --
Rate insert tinyint(1) insert char(1) insert enum(''y'', ''n'')
insert tinyint(1) 234/s -- -3% -5%
insert char(1) 242/s 3% -- -2%
insert enum(''y'', ''n'') 248/s 6% 2% --
Rate insert enum(''y'', ''n'') insert tinyint(1) insert char(1)
insert enum(''y'', ''n'') 189/s -- -6% -19%
insert tinyint(1) 201/s 7% -- -14%
insert char(1) 234/s 24% 16% --
Rate insert char(1) insert enum(''y'', ''n'') insert tinyint(1)
insert char(1) 204/s -- -4% -8%
insert enum(''y'', ''n'') 213/s 4% -- -4%
insert tinyint(1) 222/s 9% 4% --
parece que, en su mayor parte, enum(''y'', ''n'')
es más rápido de insertar.
Rate select char(1) select tinyint(1) select enum(''y'', ''n'')
select char(1) 188/s -- -7% -8%
select tinyint(1) 203/s 8% -- -1%
select enum(''y'', ''n'') 204/s 9% 1% --
Rate select char(1) select tinyint(1) select enum(''y'', ''n'')
select char(1) 178/s -- -25% -27%
select tinyint(1) 236/s 33% -- -3%
select enum(''y'', ''n'') 244/s 37% 3% --
Rate select char(1) select tinyint(1) select enum(''y'', ''n'')
select char(1) 183/s -- -16% -21%
select tinyint(1) 219/s 20% -- -6%
select enum(''y'', ''n'') 233/s 27% 6% --
Rate select tinyint(1) select char(1) select enum(''y'', ''n'')
select tinyint(1) 217/s -- -1% -4%
select char(1) 221/s 1% -- -2%
select enum(''y'', ''n'') 226/s 4% 2% --
Rate select char(1) select tinyint(1) select enum(''y'', ''n'')
select char(1) 179/s -- -14% -20%
select tinyint(1) 208/s 17% -- -7%
select enum(''y'', ''n'') 224/s 25% 7% --
Seleccionar también parece ser la enum
. El código se puede encontrar aquí
TINYINT 1 Byte
CHAR(M) M Bytes, 0 <= M <= 255
hay alguna diferente?