2012-10-22 14 views
8

Mam tabelę zawierającą ponad 100 MB rekordów. Tabela ma indeks klastrowy i indeks nieklastrowy.Procedura składowana SQL Server wolniejsza niż proste zapytanie

Mogę uruchomić podstawową liczbę przy użyciu T-SQL na stole i uruchomienie trwa 1 sekundę. Kiedy wstawię to samo dokładne zapytanie liczenia do procedury przechowywanej, uruchomienie trwa 12 sekund.

Przyjrzałem się planowi wykonania zarówno dla standardowego zapytania, jak i dla procedury przechowywanej i obydwa korzystają z indeksu nieklastrowanego.

Nie wiem, dlaczego procedura składowana jest tak powolna w porównaniu do standardowego zapytania.

Przeczytałem kilka rzeczy o ponownym indeksowaniu w takiej sytuacji, ale nie jestem pewien, dlaczego muszę to zrobić. Ponowne indeksowanie trwa kilka godzin, więc chcę się upewnić, że to zadziała.

Każda pomoc w tej sprawie byłaby świetna.

Dzięki

UPDATE

Oto procedura przechowywana:

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 

i tutaj jest średnia zapytania:

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

Próbowałem uruchomić go bez parametrów a SP biegnie szybciej (1 sekunda). Zakładam więc, że ma to coś wspólnego z parametrami.

+1

można pokazać nam trochę SP, doe przechodzą w dowolnych parametrów? –

+0

Myślę, że musisz pokazać swoje zapytanie i SP. –

+1

Może się zdarzyć, że wypróbowałeś zapytanie ze stałymi i parametry używania procedury zamiast tych stałych. Proponuję utworzyć przykład SQLFiddle lub zamieścić kilka szczegółów na temat schematu i zapytania/sp –

Odpowiedz

16

Spróbuj zmienić SP użyciem lokalne kopie zmiennych przekazywanych w.

Coś

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 

znalazłem wcześniej, że ze względu na parametr Snffing, SP może działać dużo wolniej, ale wydajność powraca po użyciu kopii zmiennych.

What is Parameter Sniffing ?

SQL Server : Parameter Sniffing

+0

Dzięki za pomoc, ale już to wypróbowałem. To nie przyspiesza. – Sequenzia

+1

wow! Dziękuję za to! Nie mogłem znaleźć problemu w moim SP, dopóki nie znalazłem tego posta! wielkie dzięki! – artsylar

+0

@Sequenzia Dzięki –

1

Zawsze można spróbować wykonać go jako dynamiczny sql:

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

Przy pierwszym uruchomieniu procedury przechowywanej, SQL Server będzie musiał opracować procedurę przechowywaną , co może trochę potrwać. @Astander wspomniał o sniffingu parametrów - który jest prawidłowym punktem i może skosić wyniki.

Niektóre inne czynniki do rozważenia są (podczas gdy nie powinny one naprawdę wyjaśnić objawy):

  • Można wymusić poziom blokady, np WITH (NOLOCK) po nazwie tabeli, która może rozwiązać problem (ale pamiętaj, że w ten sposób można uzyskać niedokładne wyniki).
  • Być może trzeba zaktualizować statystyki na stole lub defragmentacji indeksów
Powiązane problemy