2011-12-05 12 views
5

To pytanie nie tyle dotyczy znalezienia rozwiązania, jak uzyskania wyjaśnienia dla zachowania bizarrest, jakie kiedykolwiek widziałem z serwera SQL.Wydajność procedury zapisanej - jest WILD?

miałem procedurę przechowywaną z następującym podpisem:

alter procedure MySP @param1 uniqueidentifier, 
        @param2 uniqueidentifier, 
        @param3 uniqueidentifier 

otrzymuje pewien zbiór parametrów, to Proc brał bardzo długi czas uruchamiania z C# (przy użyciu SqlCommand.ExecuteReader()) - około 2 minut. Przy użyciu tych samych parametrów w bezpośredniej sesji zapytania, SP uruchomił się w ciągu 2 sekund.

Zajęło to dużo czasu, a ja nawet nie starają się wyjaśnić, jak natknęliśmy się na to rozwiązanie, ale to, co zrobiliśmy:

Na początku SP, zadeklarowaliśmy 3 zmienne lokalne i przypisane im wartości parametrów, tak jak:

declare @param1_copy uniqueidentifier, 
     @param2_copy uniqueidentifier, 
     @param3_copy uniqueidentifier 

select @param1_copy = @param1, 
     @param2_copy = @param2, 
     @param3_copy = @param3 

a następnie w pozostałej części SP my podstawiony wszystkie odniesienia do parametrów wejściowych z lokalnej kopii.

Voila. SP wykonano w mniej niż 2 sekundy. A zespół tutaj jest oszołomiony.

A teraz, panie i panowie, czy ktoś może wyjaśnić to zachowanie?

Odpowiedz

8

To brzmi jak parameter sniffing.

Z definicji Microsoft:

„Parametr wąchania” odnosi się do procesu, w którym środowisko wykonanie SQL Server „wącha” bieżące wartości parametrów podczas kompilacji lub rekompilacji i przekazuje je dalej do optymalizatora zapytań, tak aby może być wykorzystany do generowania potencjalnie szybszych planów wykonywania zapytań. Słowo "current" odnosi się do wartości parametrów obecnych w wywołaniu instrukcji, które spowodowały kompilację lub rekompilację.

Wygląda na to, że już zorientowali się jedną poprawkę, kolejna byłoby użyć EXEC ... Z rekompilacji:

podczas wykonywania procedury przechowywanej z nietypowych wartości parametrów, „EXEC ... Z RECOMPILE "można użyć, aby upewnić się, że świeży plan zapytania nie zastąpi istniejącego buforowanego planu, który został skompilowany przy użyciu typowych wartości parametrów.

+1

Niesamowite. Natknęliśmy się na rozwiązanie podręcznika, nie zdając sobie z tego sprawy! –

3

Proponuję przeczytać znakomity artykuł Erlanda Sommarskoga: Slow in the Application, Fast in SSMS? Understanding Performance Mysteries.

Zawiera szczegółowe informacje na ten temat.

Ogólnie rzecz biorąc, gdy plan zapytania jest buforowany, niektóre ustawienia zapytania są używane w kluczu pamięci podręcznej. Te ustawienia są różne w domyślnych ustawieniach SSMS, niż w domyślnych ciągach połączeń, więc mogą istnieć różne plany kwerend.

+0

Prawdopodobnie najlepiej użyć innego słowa niż "parametr", aby uniknąć pomyłki z parametrami procedury składowanej. –

+0

@MartinSmith - punkt fair. Zmieniono na "ustawienia" - co myślisz? – Oded

+0

Wydaje mi się to dobre. DMO można znaleźć w 'sys.dm_exec_plan_attributes' –

0

Miałem podobną sytuację, gdy miałem parametr typu xml i zajmowałem dużo czasu, aby wykonać.Zrobiłem to samo i utworzyłem zmienną lokalną i przekazałem wartość parametru i zadziałało super szybko :)

Gdy SQL zaczyna kompilować SP, aby utworzyć swój plan wykonania, bierze pod uwagę wartości przekazane w jego parametrach do wpływać na plan wykonania. Ale jeśli przypiszesz wartości parametrów do zmiennej lokalnej i użyjesz tej zmiennej w całym kodzie SP, to SQL nie uwzględni parametrów w celu wpłynięcia na plan wykonania, stąd otrzymasz szybszą odpowiedź z zapytania.

Powiązane problemy