Czy lepiej byłoby, gdyby plany zapytań zostały podzielone według instrukcji ponownego użycia?

11

Z mojej ograniczonej wiedzy o tym, jak plany kwerend są kompilowane, przechowywane i pobierane przez zapytania, rozumiem, że zapytanie składające się z wielu instrukcji lub procedura składowana wygeneruje swój plan zapytań, który będzie przechowywany w pamięci podręcznej planu zapytań do wykorzystania przez zapytanie w przyszłych wykonaniach.

Myślę, że ten plan jest pobierany z pamięci podręcznej planu zapytań za pomocą skrótu zapytania, co oznacza, że ​​jeśli zapytanie jest edytowane i wykonywane, skrót jest inny i generowany jest nowy plan, ponieważ w pamięci podręcznej planu zapytania nie można znaleźć pasującego skrótu.

Moje pytanie brzmi: jeśli użytkownik wykonuje instrukcję, która jest jedną z instrukcji w zapytaniu zawierającym wiele instrukcji, czy może użyć tej odpowiedniej części planu zapytań, która znajduje się już w pamięci podręcznej dla zapytania zawierającego wiele instrukcji? Oczekuję, że odpowiedź brzmi „nie”, ponieważ wartości skrótu oczywiście nie będą pasować, ale czy lepiej byłoby mieszać każdą instrukcję w zapytaniu złożonym z wielu instrukcji, aby mogły być używane przez użytkowników uruchamiających poszczególne instrukcje z zapytania?

Oczekuję, że są komplikacje, których nie biorę pod uwagę (i to o nich naprawdę chcę wiedzieć), ale wydaje się, że moglibyśmy przechowywać ten sam „plan zestawień” w wielu planach zapytań, zajmujących więcej miejsca i zajmujących więcej Procesor i czas do wygenerowania.

Może po prostu pokazywał moją ignorancję.

James Anderson
źródło
dbidi objectidoba mają, is_cache_key=1więc nie będziesz mógł ponownie wykorzystać planów między różnymi skompilowanymi obiektami.
Martin Smith

Odpowiedzi:

11

Jeśli użytkownik wykonuje instrukcję będącą jedną z instrukcji w zapytaniu zawierającym wiele instrukcji, czy może użyć tej odpowiedniej części planu zapytań, która znajduje się już w pamięci podręcznej dla zapytania zawierającego wiele instrukcji?

Nie. Podstawową jednostką ponownego użycia planu w SQL Server jest partia .

Czy lepiej byłoby zaszyfrować każdą instrukcję w zapytaniu złożonym z wielu instrukcji, aby mogły być używane przez użytkowników uruchamiających poszczególne instrukcje z zapytania?

System dostosowany do wysokiego poziomu ponownego użycia planu umieści wspólny kod (o odpowiedniej ziarnistości) w obiektach wielokrotnego użytku (np. Procedurach, funkcjach, wyzwalaczach) na SQL Server. Będzie również jawnie sparametryzować dowolny kod generowany przez aplikację lub kod po stronie klienta. W celu maksymalnego ponownego wykorzystania planu wygenerowane partie powinny różnić się tylko wartościami parametrów.

Spodziewam się, że są komplikacje, których nie biorę pod uwagę

Wygląda na to, że pytasz, dlaczego SQL Server został zaprojektowany do buforowania i ponownego użycia na poziomie partii, a nie na poziomie instrukcji. Wątpię, by ktokolwiek poza oryginalnymi projektantami mógł odpowiedzieć na to pytanie autorytatywnie. W każdym razie wydaje mi się, że partia jest naturalną ziarnistością w użyciu, ponieważ jest względnie niezależną naturalną jednostką pracy i stanowi rozsądny kompromis między złożonością wdrożenia a prawdopodobieństwem ponownego użycia planu.

Jest kilka rzeczy, które sprawiają, że partie nie są całkowicie samowystarczalne (na przykład lokalne tabele tymczasowe tworzone i do których odwołuje się między granicami procedury składowanej). Te wyjątki zmniejszają ortogonalność i przez lata były powiązane z nieoczekiwanymi zachowaniami „projektowymi” i błędami.

Paul White 9
źródło