¿El orden de las cláusulas where es importante en SQL?

121

Digamos que tengo una tabla llamada que PEOPLEtiene 3 columnas ID, LastName, FirstName, ninguna de estas columnas está indexada.
LastNamees más único y FirstNamemenos único.

Si hago 2 búsquedas:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F"

Creo que el segundo es más rápido porque el criterio más exclusivo ( LastName) viene primero en la wherecláusula, y los registros se eliminarán de manera más eficiente. No creo que el optimizador sea lo suficientemente inteligente como para optimizar el primer sql.

¿Es correcto mi entendimiento?

Ziyang Zhang
fuente
8
No, esa orden no importa - cualquier optimizador de consultas decente se verá en todo el cláusulas WHERE y averiguar la forma más eficiente para satisfacer esa consulta
marc_s
3
¿Cuáles fueron sus observaciones cuando ejecutó estas dos declaraciones? ¿Cómo eran los planes de ejecución?
Conrad Frix
3
¿Te refieres a un RDBMS específico? De hecho, hay diferencias.
Bjoern
66
Posible duplicado de SQL: ¿importa el orden de las condiciones WHERE?
Conrad Frix

Respuestas:

101

No, ese orden no importa (o al menos: no debería importar).

Cualquier optimizador de consultas decente examinará todas las partes de la WHEREcláusula y descubrirá la forma más eficiente de satisfacer esa consulta.

Sé que el optimizador de consultas de SQL Server elegirá un índice adecuado, sin importar en qué orden tenga sus dos condiciones. Supongo que otros RDBMS tendrán estrategias similares.

¡Lo que importa es si tiene o no un índice adecuado para esto!

En el caso de SQL Server, es probable que use un índice si tiene:

  • un índice en (LastName, FirstName)
  • un índice en (FirstName, LastName)
  • un índice en just (LastName), o just (FirstName)(o ambos)

Por otro lado, nuevamente para SQL Server, si usa SELECT *para tomar todas las columnas de una tabla y la tabla es bastante pequeña, entonces hay una buena posibilidad de que el optimizador de consultas solo haga un escaneo de tabla (o índice agrupado) en lugar de usar un índice (porque la búsqueda en la página de datos completa para obtener todas las demás columnas se vuelve demasiado costosa muy rápidamente).

marc_s
fuente
Si no hay índice (es), op podría ser correcto, dependiendo de los datos. Hacer un curso como este sin índices, sería una decisión extraña ...
Tony Hopkinson
@ TonyHopkinson: No lo creo, incluso sin índices dudo que haya alguna diferencia. Después de todo: sin índices, ¿qué más que un escaneo completo de tabla puede hacer el RDBMS, realmente?
marc_s
2
Nota al margen interesante con el servidor SQL, aparentemente el orden de NO EXISTE dentro de los predicados puede realmente influir en la creación del plan: bradsruminations.blogspot.com/2010/04/looking-under-hood.html
Justin Swartsel
3
¡Una cosa extraña es que para la primera ejecución de una consulta el orden de condiciones en una cláusula WHERE IMPORTA! Tenía dos condiciones, algo como: WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0y recibí un DIVIDE BY 0error. Después de cambiar el orden de las condiciones, la consulta se ejecutó con éxito. Luego volví a cambiar la orden, así que esperaría recibir el error nuevamente, ¡pero esta vez funcionó! Al final, mi conclusión fue que, para la primera ejecución, la orden es importante, hasta que se construye el plan de ejecución. 'no importa' porque el plan optimizador / ejecutivo se encargará de ello
Radu Gheorghiu
1
Me gusta que hayas dicho, "... o al menos: no debería importar". Estoy totalmente de acuerdo. A veces importa, por desgracia. He visto casos en los que SQL era demasiado complejo para que lo manejara el optimizador, y cosas como el orden de columnas y el orden de unión de tablas marcaron la diferencia. Depende del RDBMS, la complejidad de la instrucción SQL e incluso la versión. Un SQL muy complejo puede dar lugar a malas decisiones del optimizador o al uso de valores predeterminados codificados en el código del optimizador.
Victor Di Leo
19

El orden de las cláusulas WHERE no debería hacer una diferencia en una base de datos que cumpla con el estándar SQL. El orden de evaluación no está garantizado en la mayoría de las bases de datos.

No piense que a SQL le importa el orden. Lo siguiente genera un error en SQL Server:

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0

Si la primera parte de esta cláusula se ejecutara primero, solo los nombres de tablas numéricas se convertirían como enteros. Sin embargo, falla, proporcionando un claro ejemplo de que SQL Server (como con otras bases de datos) no se preocupa por el orden de las cláusulas en la instrucción WHERE.

Gordon Linoff
fuente
¿Qué tiene que ver esa consulta que causa un error con el orden de evaluación del predicado WHERE?
Jim
77
@Jim Si ISNUMERIC(table_name) = 1se evaluó primero, CASTsolo se llamaría para nombres de tablas numéricas. Pero como no se evalúa primero, también CASTse evalúa para nombres de tabla no numéricos, lo que causa el mensaje de error.
hibbelig
2
Excelente aclaración
neeohw
Solo para asegurarme de que verifiqué si intercambiar las condiciones haría que el servidor SQL las manejara al revés, pero falla en ambos sentidos. Creo que esto puede significar cualquiera de dos cosas: (1) No está optimizando tan bien como podría o (2) Es un error en tiempo de compilación y SQL ni siquiera comienza a intentar comparar nada, rescatando preliminarmente. Mi conjetura es que es nr. 2.
Louis Somers
9

ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3 Orden de evaluación de la regla

...

Cuando la precedencia no está determinada por los formatos o por paréntesis, la evaluación efectiva de las expresiones generalmente se realiza de izquierda a derecha. Sin embargo, depende de la implementación si las expresiones se evalúan realmente de izquierda a derecha, particularmente cuando los operandos u operadores pueden provocar condiciones o si los resultados de las expresiones se pueden determinar sin evaluar completamente todas las partes de la expresión.

copiado de aquí

03Usr
fuente
2

No, todos los RDBM comienzan primero analizando la consulta y optimizándola reordenando su cláusula where.

Dependiendo de qué RDBM que esté utilizando puede mostrar cuál es el resultado del análisis (busque el plan de explicación en Oracle, por ejemplo)

METRO.

poussma
fuente
Lo hace según los índices. Entonces es indirecto en términos de contenido.
Tony Hopkinson
1

Declaración OP original

Creo que el segundo es más rápido porque el criterio más exclusivo (Apellido) viene primero en la cláusula where, y los registros se eliminarán de manera más eficiente. No creo que el optimizador sea lo suficientemente inteligente como para optimizar el primer sql.

Supongo que está confundiendo esto con la selección del orden de las columnas al crear los índices en los que debe colocar las columnas más selectivas primero que la segunda más selectiva, etc.

Por cierto, para las dos consultas anteriores, el optimizador del servidor SQL no realizará ninguna optimización, pero utilizará el plan Trivila siempre que el costo total del plan sea menor que el costo del umbral de paralelismo.

Gulli Meel
fuente
0

Es cierto hasta donde llega, suponiendo que los nombres no estén indexados. Sin embargo, diferentes datos lo harían mal. Para descubrir qué forma de hacerlo, que podría diferir cada vez, el DBMS tendría que ejecutar una consulta de recuento distinta para cada columna y comparar los números, que costaría más que simplemente encogerse de hombros y seguir adelante.

Tony Hopkinson
fuente