2011-03-25 17 views
10

Consulta 1: (la velocidad del rayo)¿Por qué sp_executesql correr más lento cuando se pasan los parámetros como argumentos

sp_executesql "select * from tablesView where Id = 1" 

vs

Consulta 2: (demasiado lento)

sp_executesql "select * from tablesView where Id = @Id", N"@Id int", @Id=1 

tablesView - a view containing multiple joins

LINQ siempre convierte las consultas a la forma Query2 y, por lo tanto, el rendimiento es realmente malo.

Preguntas: Necesito un motivo para la lentitud query2, y cualquier resolución si hay una. Y una resolución para LINQ.

---- Comentarios adicionales:

éxito el rendimiento es sin duda debido a las 2 columnas que están utilizando las funciones de clasificación (ROW_NUMBER), pero no puedo evitar que los necesito.

+0

¿Tiene una gran cantidad de filas con el ID = 1? –

+0

@Lasse, incluso si tengo 50 registros, la diferencia es enorme. al igual que 0 segundos frente a 10 segundos, una cosa es seleccionar * de la tabla, generalmente es una vista con muchas combinaciones. – WhoIsNinja

+0

¿Cuál es el tipo de datos pasado para '@ id'? Puede tener un yeso implícito impidiendo el uso de un índice. –

Respuesta

0
  1. Evitar el uso de SELECT *
  2. ADO.NET 3.5 hay "parámetro quessing" en LINQ 1 = 2345 = TINYINT SMALLINT 76.357.242 = INT .. en ADO.NET 4.0 parámetro quessing se sustituye con los datos INT por defecto tipo 1 = INT, 2335 = INT, INT = 76357242)
+0

Nunca uso select *, esto fue solo por ejemplo. – WhoIsNinja

7

voy a salir en un miembro aquí y se supone que tiene una gran cantidad de filas donde ID = 1.

Si no se , por favor corrigeme.

Una posible razón de que SQL Server está procesando su consulta lenta es que se ve en la consulta y se va:

hmm, me pregunto lo que va a pasar para ese parámetro.
¿va a ser 1? donde tengo alrededor de un montón de filas?
o tal vez 1742, en la que tengo sólo 3
Sólo que no sé, lo mejor hacer un recorrido de tabla para asegurarse de producir un plan de ejecución que cubrirá todas mis bases

Si una columna, o un conjunto de columnas, tiene baja selectividad (es decir, el número de valores únicos es mucho menor que el número de filas), SQL Server algunas veces revertirá a un tablescan o similar, solo para obtener todas las filas de manera determinista.

Al menos esa ha sido mi experiencia. En particular, he visto el mismo comportamiento cuando selecciono el rango de fechas en tablas con datos de tiempo determinado, haciendo un WHERE dt <= @dt AND dt >= @dt para obtener todas las filas donde @dt está dentro de un período de tiempo en esa fila, revierte a un escaneo de tabla, y luego, cuando coloco la fecha real en el SQL como literal, se ejecuta mucho más rápido.

El problema aquí es la selectividad, SQL Server no sabe cómo atender mejor todos los escenarios al construir un plan de ejecución para su declaración, por lo que tratará de adivinar.

Intente agregar una sugerencia de consulta para especificar valor típico de para el parámetro, es decir.:

sp_executesql "select * from tablesView where Id = @Id option (optimize for (@id = 1742))", N"@Id int", @Id=1 
+0

optimize for does not help, moroever no puedo pedirle a linq que agregue optimize dentro de la consulta que crea. :( – WhoIsNinja

+0

Y hablando de registros, habrá millones de registros devueltos si no hay cláusula where en esta consulta, ya que la vista contiene combinaciones entre tablas enormes – WhoIsNinja

+1

1. ¿Quién dijo algo acerca de la cláusula No where? intente ejecutar el SQL con una cláusula de optimización por y mirando las diferencias? y 3) ... ¿es un ORM que aún no conoce sus datos el mejor enfoque? –

2

Esto podría ser un parámetro oler problema. Intente incluir la línea:

OPTION (RECOMPILE) 

al final de su consulta SQL.

Hay un artículo explicando lo que aquí inhalación de parámetro es: http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

+0

Aunque no pude usar esto directamente, fue la respuesta a mi problema, es decir, que los parámetros causaban escaneos de tabla en lugar de usar índices. El uso de OPTION (RECOMPILE) obligó a la vista subyacente a utilizar un plan que utiliza índices de tabla. Desafortunadamente no pude hacer uso de esto ya que mi analizador de SQL middleware no puede aceptar la sintaxis. Mi solución fue construir el SQL sin los parámetros, efectivamente codificando los valores en la consulta. No es ideal, pero evitó que la consulta se convirtiera en sp_executesql. – Paul

Cuestiones relacionadas