2011-10-24 15 views
5

Sto tentando di eseguire una query da ADO.NET utilizzando SQL Server 2008R2. Sto usando un CTE per fornire il paging e l'aggiunta di parametri per @Offset e @Limit, che sono entrambi interi.Timeout ADO.NET ma funziona correttamente in SSMS

Sto costruendo una query parametrizzata in base agli input dell'utente. Il risultato finale è questo:

;WITH Results_CTE AS (
    SELECT ld.* , ROW_NUMBER() OVER (ORDER BY Key_Field) AS RowNum 
    FROM list..List_Data ld 
    WHERE VALUE_2010 IS NOT NULL 
    AND Postcode LIKE @Postcode + '%' 
) SELECT * FROM Results_CTE 
    WHERE RowNum > @Offset AND RowNum < @Offset + @Limit 
OPTION (RECOMPILE) 

sto usando pochi, come le clausole che è il motivo per cui ho OPTION RECOMPILE. Se io dichiaro i parametri tramite SSMS e correre in questo modo:

declare @postcode varchar(10) = 'SW1 1AA'; 
declare @Offset int = 0; 
declare @Limit int = 10; 

ricevo un tempo di risposta molto rapido (meno di 1s). Se provo questo con ADO.NET, tuttavia, ci vorrà per sempre. Ho provato ad aggiungere i parametri con entrambi questi:

cmd.Parameters.AddWithValue("@Offset", startRowIndex) // times out 
cmd.Parameters.AddWithValue("@Limit", limit) 

cmd.Parameters.Add(New SqlParameter("@Offset", SqlDbType.BigInt)) // also times out 
cmd.Parameters.Item("@Offset").Value = startRowIndex 
cmd.Parameters.Add(New SqlParameter("@Limit", SqlDbType.BigInt)) 
cmd.Parameters.Item("@Limit").Value = limit 

Se ci sono solo un paio di righe restituite dalla prima query e anche se ho cadere il filtraggio @Offset e @Limit, ottengo un tempo di risposta decente. C'è un modo per accelerare l'utilizzo di e?

EDIT: sto passando nel parametro @postcode (che è una stringa in .NET tramite questo:

cmd.Parameters.AddWithValue("@Postcode", normalizedPostcode) 
+0

@close voter. Questo non è un dupe. La domanda precedente riguardava la spiegazione di comportamenti diversi con variabili e parametri. I due sono trattati in modo diverso da SQL Server. –

+0

Puoi mostrare il codice in cui passi nel parametro '@ postcode'? –

+0

È sicuramente il timeout SQL? Non c'è alcuna possibilità che il suo timeout provi a ottenere una connessione (ad esempio perché hai ancora un sacco di connessioni aperte quando lo fai) o qualcos'altro? – Chris

risposta

7

Il codice ADO.NET sta passando in un parametro di a different datatype rispetto a quello che si sta testando in SSMS e si stanno ottenendo i problemi del cast impliciti.

non utilizzare

cmd.Parameters.AddWithValue("@postcode", normalizedPostcode) 

come questo si auto creare unParametroe riceverai cast impliciti nel tuo piano di esecuzione, il che significa che non è possibile utilizzare un indice. Invece, passare invece un parametro creato esplicitamente del tipo varchar.

cmd.Parameters.Add("@postcode", SqlDbType.Varchar, 10) 
+0

Consiglio eccellente. La sintonizzazione esatta dei parametri in .NET sul DBType ottiene una risposta più o meno immediata. – Echilon

2

1) Per parametro parametro @postcode please specify the length.

cmd.Parameters.Add("@postcode", SqlDbType.VarChar, 10).Value = str

2) Riscrivere la query:

;WITH Results_CTE AS (
    SELECT ld.Key_Field, ROW_NUMBER() OVER (ORDER BY Key_Field) AS RowNum 
    FROM list..List_Data ld 
    WHERE VALUE_2010 IS NOT NULL 
    AND Postcode LIKE @Postcode + '%' 
) SELECT * FROM Results_CTE a 
INNER JOIN list..List_Data b ON a.Key_Field = Key_Field 
WHERE RowNum > @Offset AND RowNum < @Offset + @Limit 
--OPTION (RECOMPILE) 

Nota 1: Presumo che Key_Field è la chiave primaria (cluster) per List_Data tavolo.

Nota 2: verificare se si dispone di un indice su VALUE_2010 e campi di codice postale. Se hai SQL 2008+, puoi creare un indice filtrato:

--UNIQUE if Postcode has unique values for VALUE_2010 IS NOT NULL 
CREATE [UNIQUE] INDEX aaa 
ON MySchema.List_Data (Postcode) 
WHERE VALUE_2010 IS NOT NULL 
+0

Questo sembra migliorare la velocità di alcuni millisecondi, ma varia. Non posso ferire per buona misura. – Echilon

Problemi correlati