Considere una tabla de valores y hashes, así:
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| val | char(9) | NO | | NULL | |
| val_hashed | char(50) | YES | | NULL | |
+------------+----------+------+-----+---------+----------------+
La siguiente consulta finaliza en 0.00 segundos:
SELECT * FROM hashes ORDER BY 1 DESC LIMIT 1;
Sin embargo, esta consulta toma 3 min 17 segundos:
SELECT val FROM hashes ORDER BY 1 DESC LIMIT 1;
Veo que mientras se ejecuta la consulta, la lista de procesos la muestra como estado Sorting result
. La situación es completamente reproducible. Tenga en cuenta que hay otro proceso que realiza INSERT
operaciones en la tabla continuamente.
¿Por qué la consulta más específica tardaría más en ejecutarse que la *
consulta? Siempre he creído que las *
consultas deben evitarse específicamente por razones de rendimiento.
mysql
performance
select
dotancohen
fuente
fuente
id
para encontrar la primera fila. El segundo necesita ordenar el resultado completo en laval
columna (sin indexar) .ORDER BY NUMBER
sintaxis es bastante propensa a errores.SELECT *
combinado con un índice de columna enORDER BY
está ofuscando qué columna se está ordenando, otra razón para evitar*
s ...*
que no es explícito. Así que decir "dame todas las columnas y ordenar por la tercera" es tan determinista como decir "ve al supermercado y dime cuántos semáforos pasaste"Respuestas:
La frase se
ORDER BY 1
refiere a diferentes columnas; en el primero seráid
, en el segundoval
. Comoid
es la clave, se indexará yorder by
será una cantidad de trabajo trivial. Sinorder by val
embargo, para que el sistema tenga que recuperar cada fila, ordenar la tabla completaval
y luego elegir solo una de esas filas.Cambia ambas consultas
order by id
y creo que tus tiempos de ejecución serán casi idénticos.fuente
MG explica bien la diferencia de rendimiento en su consulta. Voy a abordar esto:
select *
no conlleva sanciones particulares por sí mismo, es problemático cuando se usa incorrectamente. En una consulta de una sola tabla, funciona bien. ahora une esa tabla a otra con 20 columnas, y luego agrega combinaciones a otras 5 tablas con muchas columnas cada una. AHORA es un problema. También lo son las personas que enseñan banda ancha, "nunca hacen X" sin explicar por qué.fuente
SELECT *
podría ser un problema incluso para una consulta de una sola tabla. Por ejemplo,SELECT * FROM hashes ORDER BY val;
probablemente hará un escaneo completo de la tabla y luego una ordenación, mientrasSELECT val FROM hashes ORDER BY val;
que solo hará un escaneo de índice completo, y no ordenará (suponiendo que exista un índice en val). Por lo tanto, nunca está de más seleccionar solo los resultados que necesitamos.select(*)
única se utiliza como sub -seleccione? Dado que es una selección integrada, ¿no sería MySQL lo suficientemente inteligente como para descubrir las columnas reales que deben seleccionarse?