2010-02-27 17 views
74

Estoy en el proceso de crear una tabla y me hizo pensar.SQL SELECT speed int vs varchar

Si almaceno, digamos autos que tengan una marca (fx BMW, Audi ect.), ¿Habrá alguna diferencia en la velocidad de consulta si almaceno la marca como un int o varchar.

Así es

SELECT * FROM table WHERE make = 5 AND ...; 

más rápido/más lento que

SELECT * FROM table WHERE make = 'audi' AND ...; 

o va a la velocidad más o menos lo mismo?

+1

Gracias por todas sus respuestas e información adicional. Has demostrado mi sospecha y has hecho mi elección fácil. – googletorp

Respuesta

72

Las comparaciones de Int son más rápidas que las comparaciones varchar, por el simple hecho de que los ints ocupan mucho menos espacio que los varchar.

Esto es válido tanto para el acceso indexado como para el no indizado. El camino más rápido es una columna int indexada.


Como veo que haya etiquetado la postgreql cuestión, que podría estar interesado en el uso del espacio de los diferentes tipos de fecha:

+9

Te refieres a la página 7.4. En las versiones modernas, ocupan 1 byte + longitud si tiene <126 bytes.También tenga en cuenta que las cadenas de razones son mucho más lentas a menudo porque la comparación sensible a la intercalación es muy costosa; no es que la cadena ocupe más espacio. Pero el resultado final es el mismo, por supuesto. –

+0

@Magnus - gracias por el aviso. Siéntete libre de editar mi respuesta ya que veo que tienes suficientes puntos de rep. –

+0

"no es que la cadena ocupe más espacio" ... las cadenas de caracteres por encima de los tamaños mínimos ocupan mucho más espacio que incluso los números de alta precisión, porque un número (singular) tiene una unidad fija, las cadenas siempre son agregadas tipos. 8 bytes para un número de 64 bits 4 bytes por carácter en una cadena, que incluye un byte de longitud o estructura; u otro personaje terminador para implementaciones increíblemente ingenuas ... – MrMesees

1

Si activa indexando en cualquiera de los campos, será más rápido. En cuanto a su pregunta, creo que int es más rápido que varchar.

4

En general, el int será más rápido. Cuanto más largo es el varchar más lento se consigue

2

Consejo: Si los valores posibles para el campo hacen se Nunca (o rara vez) el cambio, puede utilizar ENUM como un compromiso. Combina buena velocidad con buena legibilidad.

+1

Interesante, ¿cómo será la diferencia de velocidad entre ENUM e int? – googletorp

+0

¿PostgresSQL tiene un tipo de datos 'enum'? Pensé que era específico de MySQL. –

+0

Postgres tiene ENUM, pero no creo que se implemente del mismo modo que MySQL. http://www.postgresql.org/docs/current/static/datatype-enum.html – googletorp

15

Será un poco más rápido usando un int en lugar de un varchar. Más importante para la velocidad es tener un índice en el campo que la consulta puede usar para encontrar los registros.

Hay otra razón para usar un int, y es para normalizar la base de datos. En lugar de tener el texto 'Mercedes-Benz' almacenado miles de veces en la tabla, debe almacenar su identificación y tener la marca almacenada una vez en una tabla separada.

+0

¿Podría explicar más? ¿Quiere decir en lugar de 'Mercedes-Benz' para almacenar miles de veces id' 1'. Por ejemplo, la tabla 'car_brands', las columnas' Brands' y 'Id'. Fila 'Mercedes-Benz' y' 1'. Y en la columna de la tabla principal 'Marcas 'y valor' 1'. Y cuando 'SELECT', entonces primero obtienes' Id' de la tabla 'car_brands' y luego' SELECT Something FROM main_table WHERE Brands = (SELECT Id FROM car_brands WHERE Marcas = Mercedes-Benz) '. O algún otro enfoque? – user2118559

+3

@ user2118559: Sí, así es como lo almacenarías. Para obtener los datos generalmente usaría una unión en lugar de una subconsulta: 'seleccione algo de main_table c inner join car_brands b en b.Id = c.Brands donde b.Brands = 'Mercedes-Benz''. – Guffa

+0

¿Por qué el voto a favor? Si no explica qué es lo que cree que está mal, no puede mejorar la respuesta. – Guffa

4

Índice o no, int es mucho más rápido (cuanto más largo es el varchar, más lento se vuelve).

Otra razón: el índice en el campo varchar será mucho más grande que en int. Para tablas más grandes, puede significar cientos de megabytes (y miles de páginas). Eso hace que el rendimiento sea mucho peor, ya que solo leer el índice requiere muchas lecturas de disco.

+1

Por ejemplo, de 5 millones de registros de "audi", ¿el índice no contendría solo una copia de la cadena de "audi" y 5 millones de enteros de primary_key? ¿Sería la diferencia de tamaño realmente tan grande, ya sea vchar o entero? – lulalala

6

Descomponiendo el rendimiento real de la comparación de cadenas frente a las no flotantes, en este caso cualquier tamaño sin firmar y firmado no importa. El tamaño es en realidad la verdadera diferencia en el rendimiento. Ya sea 1byte + (hasta 126bytes) versus comparación de 1,2,4 u 8 bytes ...obviamente, los elementos no flotantes son más pequeños que las cadenas y los flotadores, y por lo tanto más amigables con la CPU en el ensamblaje.

La comparación de cadena a cadena en todos los idiomas es más lenta que algo que se puede comparar en 1 instrucción por la CPU. Incluso comparar 8 bytes (64 bits) en una CPU de 32 bits es aún más rápido que un VARCHAR (2) o más grande. * De nuevo, observe el ensamblaje producido (incluso a mano), se necesitan más instrucciones para comparar el carácter char por char que el de la CPU de 1 a 8 bytes.

Ahora, ¿cuánto más rápido? depende también del volumen de datos. Si simplemente comparas 5 con 'audi', y eso es todo lo que tiene tu DB, la diferencia resultante es tan mínima que nunca la verías. Dependiendo de la CPU, la implementación (cliente/servidor, web/script, etc.) probablemente no lo verá hasta que llegue a unos pocos cientos de comparaciones en el servidor de bases de datos (tal vez incluso un par de miles de comparaciones antes de que se note).

  • Para anular la disputa incorrecta sobre las comparaciones de hash. La mayoría de los algoritmos hash en sí mismos son lentos, por lo que no se beneficia de cosas como CRC64 y menor. Durante más de 12 años desarrollé algoritmos de búsqueda para motores de búsqueda de varios condados y 7 años para las agencias de informes crediticios. Todo lo que pueda mantener en números será más rápido ... por ejemplo, números de teléfono, códigos postales, incluso moneda * 1000 (almacenamiento) div div 1000 (recuperación) es más rápido que DECIMAL para las comparaciones.

Ozz

0

Algo relativa. Sí, las INT serán más rápidas, pero la pregunta es si se nota en su situación. ¿Los VARCHAR son solo algunas palabras pequeñas o textos más largos? y cuantas filas hay en la mesa? Si solo hay unas pocas filas, lo más probable es que esté completamente almacenado en la memoria (cuando se solicita con frecuencia), en ese caso no notará mucha diferencia. Luego, por supuesto, hay indexación, que se vuelve más importante cuando la mesa crece. El uso de SSD puede ser más rápido que HD con consultas optimizadas. Además, los buenos controladores de disco a veces aceleran las consultas> 10x. Esto podría dejar espacio para simplemente usar VARCHARs, lo que hace que las consultas de lectura y escritura sean más sencillas (sin necesidad de escribir uniones complejas) y acelerar el desarrollo. Los puristas, sin embargo, estarán en desacuerdo y siempre normalizarán todo.

16

Algunos puntos de referencia ásperas:

de 4 millones de registros en Postgres 9.x

Table A = base table with some columns 
Table B = Table A + extra column id of type bigint with random numbers 
Table C = Table A + extra column id of type text with random 16-char ASCII strings 

Resultados de 8 GB de RAM, i7, SSD portátil:

Size on disk:    A=261MB  B=292MB  C=322MB 
Non-indexed by id: select count(*), select by id: 450ms same on all tables 
Insert* one row per TX:  B=9ms/record  C=9ms/record 
Bulk insert* in single TX: B=140usec/record C=180usec/record 
Indexed by id, select by id: B=about 200us  C=about 200us 

* inserts to the table already containing 4M records 

lo que parece que para este configuración, siempre y cuando los índices quepan en la memoria RAM, el texto bigint vs 16-char no cambia la velocidad.

+0

Muy interesante. ¿Cómo es que la diferencia es insignificante? –