2013-03-15 18 views
6

Mam dynamiczny kawałek SQL. Uruchomienie trwa około 4 minut. Jeśli zamiast tego pobierze dane wyjściowe SQL i uruchomię je, zajmie to około 20 sekund. Skąd ta rozbieżność? Wiem, że stworzenie wersji SQL w wersji dynamicznej zajęłoby trochę czasu, ale nie mogę sobie wyobrazić, że jest TAK wysoka.Dynamiczny SQL trwa znacznie dłużej niż zakodowany odpowiednik

Ktoś ma jakieś pomysły? Te dwa zapytania powinny być identyczne, więc podejrzewałem, że było to dziwne z buforowaniem planu zapytań, ale tak naprawdę nie mam wielkiego pomysłu.

Edytuj: Aby wyjaśnić, co rozumiem przez przyjęcie wyników.

W dynamicznym SQL ostatnia linia jest

EXEC sp_executesql @myQuery, 
    N'@var1 INT, 
    @var2 INT, 
    @var2 INT', 
    @var1, 
    @var2, 
    @var3 

wziąłem wartość MyQuery i umieścić ją w osobnym pliku SQL. To trwa 20 sekund, podczas gdy dynamiczny, który wykorzystuje wykonanie, zajmuje 4 minuty.

Edycja 2 I usunąć parametrów. Mam ciekawe wyniki. Dynamiczna instrukcja SQL dostrzegła poprawę wydajności. Wersja zakodowana na sztywno dostrzegła ogromny hit wydajności. Obaj są teraz mniej więcej równi.

+9

Proszę zaksięgować swój kod. – Taryn

+0

Czy możesz pokazać swój kod? –

+0

Powinieneś dodać dużo więcej informacji, ale jeśli na stałe jest to znacznie szybsze, to zdecydowanie robisz coś złego. – TFennis

Odpowiedz

6

Zakładam, że korzystasz z serwera Microsoft SQL Server (oznaczono tylko twoje pytanie "sql").

W niektórych przypadkach różne wartości parametrów mogą powodować inny plan optymalizacji. Następnie plan optymalizacji jest buforowany i używany przy następnym uruchomieniu zapytania o różnych wartościach parametrów. Jednak plan optymalizacji nie jest najlepszym planem dla kolejnych wartości parametrów.

Oto artykuł na temat tego problemu i niektórych obejściach: https://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/

Więc tak - istnieją przypadki, w których za pomocą zapytania parametrycznego może spowodować niską wydajność w porównaniu do tego samego zapytania działa bez parametryzacji.

Nie możemy wiedzieć, czy ma to zastosowanie w twoim przypadku, jeśli nie masz prawa do publikowania swojego kodu.

Szanuję, że nie możesz tego zrobić - publikując w StackOverflow, you implicitly license your code and/or words with a Creative Commons license. Ale nie byłoby właściwe dzielenie się kodem należącym do twojego pracodawcy, chyba że wyrazi na to zgodę.

+0

OP ma problem z opryzacją; zapytanie bez parametryzacji działa znacznie wolniej niż zapytanie z parametryzacją. –

+0

@PieterGeerkens, tak nie czytam opisanego problemu PO. –

+0

W obu przypadkach parametryzacja vs nie może powodować różnych planów kwerend. Różne plany kwerend będą powodować różne czasy uruchamiania. –

4

Jeśli używasz SQL Server 2008 lub nowszy, należy zoptymalizować nieznanych nutą zapytania. Dodaj poniższe linie do końca dynamicznego zapytania:

OPTION (OPTIMIZE FOR (@var1 UNKNOWN, @var2 UNKNOWN, @var3 UNKNOWN)) 

eksperyment ze zmianą lub pomniejszyć trzech wejść @ zm1 @ VAR2 i @ VAR3. Tak, to naprawdę może być tak drogie, jeśli optymalizator zapytań spróbuje użyć statystyk dotyczących czegoś, co jest naprawdę ad hoc.Jeśli jedna lub więcej zmiennych jest dość przewidywalna, zoptymalizuj te pod kątem określonych wartości i zoptymalizuj pozostałe za nieznane. Sprawdź ten link, aby uzyskać więcej szczegółów.

https://blogs.msdn.microsoft.com/sqlprogrammability/2008/11/26/optimize-for-unknown-a-little-known-sql-server-2008-feature/

być jasne, to jest prawdopodobne, parametr wąchania problem jak wskazano ninjaPixel powyżej. OPTIMIZE FOR UNKNOWN może dać lepsze wyniki niż rekompilacja każdego zapytania, ponieważ optymalizator zapytań opiera się na statystykach, aby wykonać kompilację.

+0

Dzięki. Chciałem początkowo przyznać nagrodę ninjaPixel, ale ta odpowiedź jest jeszcze lepsza. –

+0

Cieszę się, że mogę pomóc – quest4truth

2

Dodaj komentarz do zapytania dynamicznego. Wstaw wartości Komentarz zmiennych @ zm1 @ var2 @ VAR3 itp

będzie wyglądać następująco:

EXEC sp_executesql @myQuery, 
    /* var1Value, var2Value, var3Value */  
    N'@var1 INT, 
    @var2 INT, 
    @var2 INT', 
    @var1, 
    @var2, 
    @var3 

Więc plan wykonania będzie skompilować tylko dla różnych wartości.

Powiązane problemy