2009-03-13 26 views

Respuesta

15

Con un optimizador de consultas decente: no debería.

Pero en la práctica, sospecho que podría.

Solo puede medir sus casos midiendo. Y las medidas probablemente cambien a medida que la distribución de datos cambie en la base de datos.

+1

+1: Si bien el 99,99% de las veces, no importa ... Acabo de encontrarme con un problema hoy en el que una consulta extremadamente simple contra campos bien indexados elegía el plan de ejecución incorrecto a menos que el orden de los dos los criterios en la cláusula WHERE fueron revertidos. Curioso: el planificador de consultas sugirió que faltaba un índice con exactamente las mismas especificaciones que el que el optimizador eligió cuando invertí la cláusula WHERE. Funnier: el orden de los criterios que fue más rápido fue * hacia atrás * en comparación con el orden del índice. Agregar una sugerencia de índice (o eliminar el ORDER BY) lo resolvió. (Estoy usando SQL Server 2005.) –

+0

No ha respondido la pregunta en absoluto –

+0

@ JᴀʏMᴇᴇ Tengo. La respuesta es: no todas las preguntas, especialmente en el caso general, tienen una respuesta. Este es un ejemplo de tal pregunta. – Richard

-4

Si cumple las condiciones ANDing, la primera no es verdadera devolverá false, por lo que el orden puede afectar el rendimiento.

+0

No veo por qué esto fue votado negativamente +1 –

+2

Voto ascendente porque cree que un voto a favor fue injusto, en lugar de porque cree que la respuesta merece un voto positivo no es una buena práctica. Creo que un optimizador de consultas volverá a organizar las reglas, en lugar de solo emplear la evaluación perezosa. – SpoonMeiser

+2

SpoonMeiser es correcto; el optimizador (al menos para SQL Server) utiliza una lógica más compleja que la simple evaluación de estilo C++. – mwigdahl

2

Todo depende del DBMS, el optimizador de consultas y las reglas, pero en general afecta el rendimiento.

Si se ordena una cláusula where de modo que la primera condición reduce significativamente el resultado, las condiciones restantes solo deberán evaluarse para un conjunto más pequeño. Siguiendo esa lógica, puede optimizar una consulta basada en el orden de condición en una cláusula where.

12

Para Transact-SQL existe una precedencia definida para los operadores en el condition de la cláusula WHERE. El optimizador puede volver a ordenar esta evaluación, por lo que no debe confiar en el comportamiento de cortocircuito para la corrección. El orden generalmente es de izquierda a derecha, pero la selectividad/disponibilidad de los índices probablemente también sea importante. La simplificación de su condición de búsqueda debería mejorar la capacidad del optimizador para manejarlo.

Ex:

WHERE (a OR b) AND (b OR c) 

podría simplificarse en

WHERE b OR (a AND c) 

Es evidente que en este caso, si la consulta se puede construir de encontrar si b tiene principio puede ser capaz de saltarse la evaluación de una yc, y por lo tanto, funcionaría más rápido. Si el optimizador puede hacer esta simple transformación, no puedo responder (puede hacerlo), pero el hecho es que probablemente no pueda realizar transformaciones arbitrariamente complejas y es posible que pueda efectuar el rendimiento de la consulta reorganizando su condición. Si b es más selectivo o tiene un índice, es probable que el optimizador pueda construir una consulta que lo use primero.

EDITAR: Con respecto a su pregunta sobre el pedido basado en la singularidad, yo asumiría que los ninguna pista que pueden proporcionar al optimizador basado en su conocimiento (real, no error u omisión) de los datos no se pudieron hacer daño. Supongamos que no hará ninguna optimización y construirá su consulta como si necesitara definirla de mayor a menor selectividad, pero no se obsesione hasta que el rendimiento sea realmente un problema.

Citando de la referencia anterior:

El orden de precedencia de los operadores lógicos no es (más alto), seguido de Y, seguido por OR. Los paréntesis pueden usarse para anular esta precedencia en una condición de búsqueda. El orden de evaluación de los operadores lógicos puede variar según las elecciones realizadas por el optimizador de consulta .

+1

-1 No existe un orden definido de evaluación, excepto en una declaración 'CASE' o (por algún motivo oscuro de compatibilidad con versiones anteriores) cuando se encadenan las condiciones' EXISTS'. [Vea este artículo para una demostración] (http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/) –

+0

@MartinSmith - Dado que he citado de la La documentación de T-SQL, diría que la observación del autor de que no es un error es discutible. Los documentos especifican claramente que los operadores en una cláusula WHERE obedecen las reglas de precedencia. Por supuesto, puede ser que la documentación esté equivocada y me hayan engañado. – tvanfosson

+1

@tvanfosson - Lamento no haber notado esa frase específica en los documentos en los que basó su respuesta, por lo que se ha retractado mi DV pero [parece que se ha corregido en versiones posteriores] (http://technet.microsoft.com/es -us/library/ms173545.aspx) para decir 'El orden de evaluación de los operadores lógicos puede variar según las elecciones realizadas por el optimizador de consultas' –

0

En el gran mayoría de los casos el optimizador de consultas determinará la forma más eficiente para seleccionar los datos que ha solicitado, independientemente del orden de los SARGS establecidas en la cláusula WHERE.

El orden está determinado por factores tales como la selectividad de la columna en cuestión (que SQL Server conoce en función de las estadísticas) y si se pueden usar índices.

6

Para SQL Server 2000/20005/2008, el optimizador de consultas generalmente le dará resultados idénticos sin importar cómo organice las columnas en la cláusula WHERE. Habiendo dicho esto, a lo largo de los años de escribir miles de comandos T-SQL he encontrado algunos casos de esquina donde el orden alteró el rendimiento. Aquí están algunas características de las consultas que parecían estar sujeto a este problema:

  1. Si usted tiene un gran número de tablas en la consulta (10 o más).

  2. Si tiene varios existe, IN, NO existe, o no, en declaraciones en su cláusula WHERE

  3. Si está utilizando anidada (expresiones de tabla común) del CTE o un gran número de CTE.

  4. Si tiene una gran cantidad de subconsultas en su cláusula FROM.

Éstos son algunos consejos sobre trata de evaluar la mejor manera de resolver el problema de rendimiento de forma rápida:

  1. Si el problema está relacionado con 1 o 2, a continuación, tratar la reordenación de la cláusula WHERE y comparar el costo del subárbol de las consultas en los planes de consulta estimados.

  2. Si el problema está relacionado con 3 o 4, intente mover las consultas secundarias y los CTE fuera de la consulta y haga que carguen las tablas temporales. El optimizador de plan de consulta es mucho más eficiente para estimar planes de consulta si reduce la cantidad de uniones complejas y subconsultas del cuerpo de la instrucción T-SQL.

  3. Si está utilizando tablas temporales, asegúrese de haber especificado las claves principales para las tablas temporales. Esto significa evitar el uso de SELECT INTO FROM para generar la tabla. En su lugar, cree explícitamente la tabla y especifique una LLAVE primaria antes de usar una instrucción INSERT INTO SELECT.

  4. Si está utilizando tablas temporales y MUCHOS procesos en el servidor también usan tablas temporales, entonces puede querer hacer una tabla de etapas más permanente que se trunque y vuelva a cargar durante el proceso de consulta. Es más probable que encuentre problemas de contención del disco si está utilizando TempDB para almacenar sus tablas de trabajo/etapas.

  5. Mueva las instrucciones en la cláusula WHERE que filtrará la mayor cantidad de datos al principio de la cláusula WHERE. Tenga en cuenta que si esta es su solución al problema, es probable que tenga un rendimiento bajo nuevamente cuando el plan de consulta se vuelva a confundir sobre la generación y elección del mejor plan de ejecución. Es mejor que encuentre una forma de reducir la complejidad de la consulta para que el orden de la cláusula WHERE ya no sea relevante.

Espero que esta información sea útil. ¡Buena suerte!

+0

+1 Esto es lo que he encontrado también: le dicen que el optimizador lo hará, pero cuando lo mida sugiere lo contrario. – Fenton

2

En teoría dos consultas cualesquiera que sean equivalentes deben producir planes de consulta idénticos. Como el orden de las cláusulas WHERE no tiene ningún efecto sobre el significado lógico de la consulta, esto debería significar que el orden de la cláusula WHERE no debería tener ningún efecto.

Esto se debe a la forma en que funciona el optimizador de consultas. En una visión generalenormemente simplificada:

  1. Primera SQL Server analiza la consulta y construye un árbol de operadores lógicos (por ejemplo JOIN o SELECT).
  2. Luego traduce estos operadores lógicos en un "árbol de operaciones físicas" (por ejemplo, "Bucles anidados" o "Análisis de índice", es decir, un plan de ejecución)
  3. Luego permuta a través del conjunto de "árboles equivalentes de operaciones físicas" "(es decir, planes de ejecución) mediante el intercambio de operaciones equivalentes, estimando el costo de cada plan hasta que encuentre el óptimo.

El segundo paso se realiza es una forma completamente nieve - simplemente elige el primer árbol física/más obvio que puede, sin embargo, en la tercera etapa, el optimizador de consultas es capaz de mirar a través de todos árboles físicas equivalentes (es decir, planes de ejecución), y siempre que las consultas sean equivalentes, no importa qué plan inicial obtengamos en el paso 2, el conjunto de planes que todos los planes deben considerarse en el paso 3 es el mismo.

(no puedo recordar los nombres reales de los árboles lógicos/físicos, están en un libro, pero por desgracia, el libro es el otro lado del mundo de mí en este momento)

Ver la siguiente serie de artículos del blog para más detalle Inside the Optimizer: Constructing a Plan - Part 1

en realidad sin embargo a menudo el optimizador de consultas no tiene la oportunidad de considerar todos los árboles equivalentes en el paso 3 (para consultas complejas no puede haber un número masivo de posibles planes), y así, después de un cierto tiempo límite, el paso 3 se acorta y la consulta optimis Tiene que elegir el mejor plan que haya encontrado hasta ahora; en este caso, no es , se considerarán todos los planes.

Hay una gran cantidad detrás de la magia de sceene que asegura que el optimizador de consultas selecciona selectiva e inteligentemente los planes a considerar, por lo que la mayoría de las veces el plan es "lo suficientemente bueno", incluso si no es el plan más rápido absoluto, probablemente no es mucho más lento que el teórico más rápido,

Lo que esto significa es que si tenemos un plan de inicio diferente en el paso 2 (que podría ocurrir si escribimos nuestra consulta de manera diferente), esto potencialmente significa que se considera un subconjunto diferente de planes en el paso 3, por lo que en teoría SQL Server puede llegar a diferentes planes de consulta para consultas equivalentes según la forma en que se escribieron.

En realidad, sin embargo, el 99% de las veces no notará la diferencia (para muchos planes simples, no habrá , ya que el optimizador realmente considerará todos los planes).Además, no puede predecir cómo va a funcionar nada de esto y, por lo tanto, las cosas que pueden parecer sensatas (como poner las cláusulas WHERE en un orden determinado) podrían no tener el efecto esperado.

Cuestiones relacionadas