2011-01-05 15 views
10

¿Cuál de las siguientes consultas será más rápido y más óptima (y por qué):INT vs VARCHAR en busca

  1. SELECT * FROM items WHERE w = 320 AND h = 200 (w y h son INT)

  2. SELECT * FROM items WHERE dimensions = '320x200' (dimensiones es VARCHAR)

+2

Señalaré que es probable que las dos columnas contengan datos más precisos que son críticos para un buen diseño de la base de datos. – HLGEM

+0

Hubiera sido una mejor comparación si hubiera declarado que comparaba la altura y el ancho como dos varchar diferentes. Tienes a todos respondiendo si esto y si ... – puck

Respuesta

5

Aquí hay algunas medidas reales. (Usando SQLite, puede intentarlo con MySQL más tarde.)

Datos = Todos 1,000,000 combinaciones de w, h ∈ {1 ... 1000}, en orden aleatorio.

CREATE TABLE items (id INTEGER PRIMARY KEY, w INTEGER, h INTEGER)

Tiempo medio (de 20 carreras) para ejecutar SELECT * FROM items WHERE w = 320 and h = 200 era 5,39 ± 0,29 mu s.

CREATE TABLE items (id INTEGER PRIMARY KEY, dimensions TEXT)

Tiempo medio para ejecutar SELECT * FROM items WHERE dimensions = '320x200' fue de 5,69 ± 0,23 mu s.

No hay una diferencia significativa, en términos de eficiencia.

Pero

Hay una gran diferencia en términos de facilidad de uso. Por ejemplo, si desea calcular el área y el perímetro de los rectángulos, el enfoque de dos columnas es fácil:

SELECT w * h, 2 * (w + h) FROM items

tratar de escribir la consulta correspondiente para el otro lado.

+0

'dimensions TEXT' ???? – ajreal

0

primero porque es más rápido para comparar los datos numéricos.

2

Probablemente la única forma de saberlo es ejecutarlo. Sospecho que si todas las columnas utilizadas están indexadas, básicamente no habría diferencia. Si INT tiene 4 bytes, tendrá casi el mismo tamaño que la cadena.

La única arruga está en cómo se almacena VARCHAR. Si utilizó un tamaño de cadena constante, podría ser más rápido que VARCHAR, pero principalmente porque su select * necesita obtenerlo.

La gran ventaja de utilizar INT es que puede hacer un filtrado mucho más sofisticado. Solo eso debería ser una razón para preferirlo. ¿Qué sucede si necesitas un rango, o solo ancho, o quieres hacer cálculos matemáticos de ancho en el filtrado? ¿Qué pasa con las restricciones basadas en las columnas o agregados?

Además, cuando obtenga los valores en su lenguaje de programación, no necesitará analizarlos antes de usarlos (lo que lleva tiempo).

EDITAR: Algunas otras respuestas mencionan comparaciones de cuerdas. Si está indexado, no habrá muchas comparaciones de cadenas hechas. Y es posible implementar algoritmos de comparación muy rápidos que no necesiten bucle byte a byte. Tendría que saber los detalles de lo que mysql hace para estar seguro.

1

segunda consulta, ya que las posibilidades para que coincida con la cadena exacta es más pequeño (que significa conjunto más pequeño de registros pero con mayor cardinalidad)

primera consulta, es probable que emparejan primera columna es más alta y más filas están potencialmente emparejados (menor cardinalidad)

por supuesto, suponiendo que el índice se definen para los dos escenarios

+0

¿No sería compensado buscando en un conjunto de datos más pequeño, ya que la primera consulta solo encontrará las filas donde coincida el primer campo, y luego buscará ese conjunto de registros para los partidos en el segundo campo? – JNK

+0

@JNK - explicó menor récord pero mayor cardinalidad, compara dos columnas más registro con menor cardinalidad en cada columna – ajreal

2

Intuitivamente, si no se crea INDEX es en esas columnas, comparación número entero parece más rápido.

En comparación entera, se compara directamente la igualdad de valores de 32 bits con los operadores lógicos.

Por otro lado, las cadenas son matrices de caracteres, será difícil compararlas. Personaje por personaje.

Sin embargo, otro punto es que, en la segunda consulta tiene 1 campo para comparar, en la primera consulta tiene 2 campos. Si tiene 1,000,000 de registros y no hay índices en las columnas, eso significa que puede tener 1,000,000 de comparaciones de cadenas en el peor de los casos (desafortunadamente el último resultado es lo que busca o no encontró)

Por otro lado, tiene 1,000,000 de registros y todos son w=320, luego los comparará también para h. Eso significa 2,000,000 comparaciones. Sin embargo, usted crea INDEXes en esos campos en mi humilde opinión, serán casi idénticos ya que VARCHAR tendrá hash (toma O(1) tiempo constante) y se compararán usando la comparación INT y tomarán O(logn) vez.

Conclusión, depende. Prefiere los índices en las columnas que se pueden buscar y usa ints.

0

Depende de los datos y los índices disponibles. Pero es bastante posible que la versión VARCHAR sea más rápida porque la búsqueda de un solo índice puede ser más rápida que dos. Si la combinación de valores proporciona un resultado único (o "principalmente" único) mientras que cada valor individual de H/W tiene entradas múltiples, entonces podría reducir el conjunto reducido a un conjunto mucho más pequeño utilizando el índice individual.

Por otro lado, si tiene un índice de columna múltiple en las columnas de enteros, probablemente sea el más eficiente.