2009-09-16 15 views
15

Tengo una tabla de usuario donde hay un nombre de usuario y columnas de aplicación. Nombre de usuario puede repetir, pero la combinación de nombre de usuario + aplicación es única, pero no tienen la restricción única salida en la tabla (para el rendimiento)Efecto de rendimiento del uso de TOP 1 en una consulta SELECT

Pregunta: ¿habrá alguna diferencia (en cuanto al rendimiento) entre:

SELECT * FROM User where UserName='myuser' AND Application='myapp' 

Y -

SELECT TOP 1 * FROM User where UserName='myuser' AND Application='myapp' 

Como combinación de nombre de usuario + aplicación es única, tanto las consultas volverá siempre hay más de un registro, por lo que TOP 1 no afecta el resultado. Siempre pensé que agregar TOP 1 realmente aceleraría las cosas ya que el servidor sql dejaría de buscar y encontró una coincidencia, pero recientemente leí en un artículo que usar TOP reducirá la velocidad de las cosas y se recomienda evitar, aunque no lo han hecho. explicado por qué.

¿Algún comentario?

¡Gracias! Andrey

+0

Gracias por la edición, Joel - por alguna razón no pude hacer las consultas como líneas de código, las seleccionaría y haría clic en el ícono de "código" y no pasaría nada. – Andrey

+0

Andrey, haga clic en el ícono antes de ingresar el código. El truco es que cualquier línea que comience con cuatro espacios se interpreta como código. Simplemente selecciono mi código en SSMS y lo sangro. Eso me da un formato perfecto. (Tengo SSMS configurado para usar espacios en lugar de caracteres de pestañas). –

Respuesta

10

Puede obtener alguna diferencia de rendimiento de solo usar top, pero el rendimiento real que obtiene al usar índices.

Si tiene un índice para los campos UserName y Application, la base de datos ni siquiera tiene que tocar la tabla hasta que haya aislado el registro individual. Además, ya se sabe por las estadísticas de la tabla que los valores son únicos, por lo que usar top no hace diferencia.

+0

Crear una índice en las dos columnas es una buena idea, pero no quiero crear un índice único, ya que ralentizará las inserciones, que son una parte fundamental de la aplicación. – Andrey

+0

¿Sabía que si cambia el índice a único ralentizará las inserciones (sobre un índice no único) o solo sospecha que lo hará? Si asume que es único, debe respaldarlo con un índice único. –

+0

Un índice único ralentizará las inserciones, ya que debe verificar su existencia antes de insertarlas, pero la diferencia debería ser bastante pequeña. Puede obtener un rendimiento de lectura algo mejor a partir de un índice único, pero la principal ventaja es que garantiza la integridad en la tabla. – Guffa

15

Si hay más de una fila en los resultados y no hay cláusula ORDER BY, el "TOP 1" ahorra una tonelada de trabajo para el servidor. Si hay una orden por cláusula, el servidor aún tiene que materializar el conjunto de resultados completo de todos modos, y si solo hay una fila, en realidad no cambia nada.

+0

Siempre devolverá una o ninguna fila, ya que la combinación de Nombre de usuario y Aplicación es única. Entonces, ¿entiendo correctamente que TOP 1 no hará absolutamente ninguna diferencia en mi caso anterior? – Andrey

+0

No diría "cero". Los optimizadores de consultas son complicados, así que lanzaría algunas palabras de comadreja como "probablemente triviales si las hubiera". –

+2

Hará toda la diferencia en el mundo para algunos valores, ninguno para el otro. Cuando solicite el usuario y la aplicación que sean los primeros en el orden físico en la tabla, el TOP 1 parecerá miracoulos, ya que detendrá el escaneo después de un registro. Cuando solicite el usuario y la aplicación cerca del extremo del árbol b, TOP 1 no hará ninguna diferencia. Lo que realmente necesitas es cubrir índices. –

4

Creo que depende del plan de ejecución de consultas que SQL genera ... En el pasado en versiones anteriores de SQL Server he visto el uso de un superfluo 'TOP' ofrecer beneficios de rendimiento definidos con consultas complejas con muchas combinaciones. Pero definitivamente no en todos los casos.

Supongo que el mejor consejo que puedo dar es probarlo caso por caso.

1

dices que no aplicas la restricción, que se traduce en que no hay un índice único en (Nombre de usuario, Aplicación) o (Aplicación, Nombre de usuario). ¿Puede la consulta usar una ruta de acceso que busca ya sea en UserName o Application? En otras palabras, ¿alguna de estas dos columnas está indexada? En caso afirmativo, el plan seleccionará el más selectivo que esté indexado y realizará un análisis de rango, posiblemente un ciclo anidado con una búsqueda de marcador si el índice no está agrupado, luego un filtro. La parte superior 1 detendrá la consulta una vez que coincida el primer filtro, pero la diferencia depende de la cardinalidad de los datos (cuántos registros encuentra la exploración de rango y cuántos satisfacen el filtro).

Si no hay un índice, realizará un escaneo en clúster completo pase lo que pase. La parte superior 1 detendrá el escaneo en la primera coincidencia, ya sea después de procesar 1 registro o después de procesar 999 mil. los registros dependen del nombre de usuario y aplicación reales ...

Lo único que hará una diferencia real es permitir que la consulta busque ambos valores, es decir. tener un índice de cobertura. La restricción se aplicaría exactamente a través de dicho índice de cobertura. En otras palabras: al desactivar la restricción, presumiblemente para el rendimiento de escritura, prepárese para pagar el precio en las lecturas. ¿Esto es importante? ¿Hizo alguna medida para confirmar que la escritura de índice adicional de la restricción amortiguaría críticamente el rendimiento?

Cuestiones relacionadas