de Cristopher Chaverri

No selecciones lo que no necesitas


select * tiene mala fama. La mayoría de personas cree que se debe a que los cambios en la definición de la tabla causan errores difíciles de detectar. Enumerar todas las columnas en el orden deseado resuelve ese problema, ¿verdad? Sí, pero eso no soluciona el segundo problema de select *.

El otro problema es que seleccionar más de una columna supone más trabajo para la base de datos. La sorpresa es que el impacto en el rendimiento puede ser enorme.

Hasta 100 veces más lento al evitar un escaneo Index-Only

En términos generales, entre menos columnas se seleccionen, menos datos deben cargarse al procesar la consulta. Sin embargo, esta relación es no lineal.

A menudo, la selección de una tabla implica dos pasos: (1) usar un índice para localizar la dirección en la que se almacenan las filas seleccionadas; (2) cargar las filas seleccionadas de la tabla. Ahora imagina que solo estás seleccionando las tablas que están presentes en el índice. ¿Por qué debería la base de datos igualmente realizar el segundo paso? De hecho, la mayoría de bases de datos no lo hacen. Pueden procesar la consulta solo con la información almacenada en el índice; de ahí el término index-only scan.

Pero ¿por qué un escaneo index-only debería ser 100 veces más rápido? Sencillo: un índice ideal almacena las filas seleccionadas una al lado de la otra. No es raro que cada página del índice contenga hasta 100 filas —una cifra aproximada, ya que depende del tamaño de las columnas indexadas—. No obstante, esto significa que solo una operación E/S podría recuperar 100 filas. Por otro lado, la tabla de datos no está organizada de esa manera (salvo excepciones). Aquí es bastante común que una página solo contenga una de las filas seleccionadas, junto con otras filas que no son de intéres para la consulta en cuestión. Así que la razón por la que un escaneo Index-Only puede ser 100 veces más rápido, es que un acceso al índice puede proporcionar fácilmente 100 filas por E/S, mientras que el acceso a la tabla normalmente recupera solo unas pocas filas por E/S.

Si se selecciona una sola columna que no está en el índice, la base de datos no puede realizar un escaneo index-only. Si se seleccionan todas las columnas, …bueno, supongo que ya sabes la respuesta.

Además, algunas bases de datos almacenan lo objetos grandes en un lugar separado (por ejemplo, LOBs en Oracle). Acceder a ellos también causa una operación E/S adicional.

Hasta 5 veces más lento debido al consumo de memoria del servidor

Aunque las bases de datos evitan almacenar resultados en la memoria principal del servidor —En su lugar, entregan cada fila después de cargarla y luego la desechan— A veces es inevitable. Por ejemplo, el ordenamiento necesita mantener todas las filas —y todas las columnas seleccionadas— en memoria para poder realizar el trabajo. De nuevo, mientras más columnas se seleccionen, más memoria necesitará la base de datos. En el peor de los casos, la base de datos incluso podría realizar un ordenamiento externo en el disco.

Sin embargo, la mayoría de bases de datos están muy bien optimizadas para este tipo de carga de trabajo. Aunque he observado con bastante frecuencia que la velocidad de ordenamiento se duplica —simplemente eliminando columnas que no se utilizan—, no recuerdo nunca haber obtenido una mejorar superior a un factor de cinco. Sin embargo, no se trata solo del ordenamiento; los hash joins son bastante sensibles al consumo excesivo de memoria. ¿No sabes qué es eso? Por favor, lee este artículo.

Estos son solo los dos principales problemas desde la vista de la base de datos. Recuerda que la red también se ve afectada y que el cliente también tiene que procesar los datos —lo cual podría suponer una carga considerable sobre la recolección de basura.

Mucha gente cree que el asterisco es el problema. Consecuentemente, creen que no hay ningún problema si su ORM lista todas las columnas por nombre. De hecho, el error está en seleccionar todas las columnas sin pensarlo —y la mayoríad de los ORMs cometen este error en nombre de sus usuarios.

Cuando se dice que “select * es malo”, utilizamos el asterisco como símbolo para ”seleccionar todo sin pensarlo”. Y ahí está lo malo. Si necesitas una frase más pegadiza para recodarlo, quédate con esta:

No se trata del asterisco, ¡idiota!

Si te gusta mi manera de explicar, te encantará mi libro Rendimiento SQL Explicado.

You can’t learn everything in one day. Subscribe the newsletter via E-Mail, Bluesky or RSS to gradually catch up. Have a look at modern-⁠sql.com as well.

Acerca del autor

Foto de Markus Winand

Markus Winand es defensor del resurgimiento del SQL. Su misión es la de presentar a los desarrolladores la evolución de SQL en el siglo XXI. Es posible contratar a Markus según disponibilidad o como orador o consultor en winand.at.

Adquiere tu libro

Portada de “Rendimiento SQL explicado”: Ardilla corriendo en la hierba

La esencia del tuning de SQL en 200 páginas

Compra ahora
(libro de bolsillo y/o PDF)

Contratar a Markus

La manera más rápida y fácil de beneficiarse de su extenso conocimiento y experiencia.
Aprende más »

Entrar en contacto con Markus

Suscríbete a listas de correoRSS FeedMarkus Winand en LinkedInMarkus Winand en XINGMarkus Winand en MastodonMarkus Winand en Bluesky
Copyright 2017-2026 Martin LE TARNEC, Markus Winand. All righs reserved.
Aspectos legales | Contacto | SIN GARANTÍA | Marcas | Privacidad y RGPD