2012-10-22 1 views
8

Ho una tabella con oltre 100 milioni di record. La tabella ha un indice cluster e un indice non cluster.La stored procedure di SQL Server è molto più lenta della query diretta

Posso eseguire un conteggio di base utilizzando T-SQL sul tavolo e ci vuole 1 secondo per l'esecuzione. Quando inserisco la stessa esatta query di conteggio all'interno di una procedura memorizzata, sono necessari 12 secondi per l'esecuzione.

Ho esaminato il piano di esecuzione per la query standard e la stored procedure e entrambi utilizzano l'indice non cluster.

Non sono sicuro del motivo per cui la stored procedure è così lenta rispetto alla query standard.

Ho letto alcune cose sulla reindicizzazione in una situazione come questa, ma non sono sicuro del motivo per cui ho bisogno di farlo. Inoltre, ci vogliono alcune ore per reindicizzare, quindi voglio assicurarmi che funzioni.

Qualsiasi aiuto su questo sarebbe fantastico.

Grazie

UPDATE

Ecco la stored procedure:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE quickCount 

@sYID INT, 
@eYID INT 

AS 
BEGIN 

SET NOCOUNT ON; 


    SELECT COUNT(leadID) 
    FROM dbo.leads 
    WHERE yearID >= @sYID 
    AND yearID <= @eYID 

END 
GO 

e qui è la query standard:

SELECT COUNT(leadID) 
FROM leads 
WHERE yearID >= 0 
AND yearID <= 99 

ho provato a farlo funzionare senza parametri e l'SP scorre più veloce (1 secondo). Quindi presumo che abbia qualcosa a che fare con i parametri.

+1

ci mostri un po 'di SP, doe si passa tutti i parametri? –

+0

Penso che dovrai mostrare la tua query e SP. –

+1

Può capitare che tu abbia provato una query con costanti e che la tua procedura utilizzi i parametri al posto di queste costanti. Ti suggerisco di creare un esempio SQLFiddle o di pubblicare alcuni dettagli sullo schema e query/sp –

risposta

16

provare a modificare le SP all'utilizzo di copie locali delle variabili passate in.

Qualcosa di simile

ALTER PROCEDURE quickCount 

@sYID INT, 
@eYID INT 

AS 
BEGIN 

SET NOCOUNT ON; 
    DECLARE @Local_sYID INT, 
      @Local_eYID INT 
    SELECT @Local_sYID = @sYID INT, 
      @Local_eYID = @eYID INT 

    SELECT COUNT(leadID) 
    FROM dbo.leads 
    WHERE yearID >= @Local_sYID 
    AND yearID <= @Local_eYID 

END 

ho trovato prima che a causa di parametri Snffing, un SP può essere eseguito molto più lento, ma la performance ritorna dopo aver usato le copie delle variabili.

What is Parameter Sniffing ?

SQL Server : Parameter Sniffing

+0

Grazie per l'aiuto, ma l'avevo già provato. Non lo rende più veloce. – Sequenzia

+1

Eeeek !!! grazie per quello! Non sono riuscito a trovare il problema nel mio SP finché non ho trovato questo post! molte grazie! – artsylar

+0

@Sequenzia Grazie –

1

Si può sempre provare a eseguirlo SQL come dinamica:

ALTER PROCEDURE quickCount 

@sYID INT, 
@eYID INT 

AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @SQL VARCHAR(max) 

    SELECT @SQL = ' 
    SELECT COUNT(leadID) 
    FROM dbo.leads 
    WHERE yearID >= '+CONVERT(VARCHAR(20),@sYID)+' 
    AND yearID <= '+CONVERT(VARCHAR(20),@eYID) 

    EXEC (@SQL) 
END 
0

La prima volta che si esegue la stored procedure, SQL Server dovrà compilare la stored procedure , che può richiedere un po 'di tempo. @Astander ha accennato al parametro sniffing - che è un punto valido e può distorcere i risultati.

Alcuni altri fattori da considerare sono (mentre non dovrebbe davvero spiegare i sintomi):

  • Si potrebbe forzare un livello di blocco, per esempio WITH (NOLOCK) dopo il nome della tabella, che potrebbe risolvere il problema (ma si noti che è possibile ottenere risultati inaccurati in tal modo).
  • Potrebbe essere necessario aggiornare le statistiche sul tavolo o deframmentare gli indici