Kiedy ustalane są wartości dla kolumn obliczanych?
- Kiedy wartość jest pobierana?
- Kiedy wartość zostanie zmieniona?
- Innym razem?
Domyślam się, że jest to pytanie dla początkujących, ponieważ nie znajduję niczego w moich wyszukiwaniach.
sql-server
computed-column
Shelby115
źródło
źródło
Bardzo łatwo to udowodnić na własną rękę. Możemy utworzyć tabelę z kolumną obliczeniową, która korzysta ze skalarnej funkcji zdefiniowanej przez użytkownika, a następnie sprawdzać plany i statystyki funkcji przed aktualizacją i po jej wybraniu oraz po niej i sprawdzać, kiedy wykonanie zostanie zarejestrowane.
Powiedzmy, że mamy tę funkcję:
I ta tabela:
Sprawdźmy
sys.dm_exec_function_stats
(nowość w SQL Server 2016 i Azure SQL Database) przed i po wstawieniu, a następnie po wybraniu:Nie widzę wywołania funkcji na wstawce, tylko na select.
Teraz upuść tabele i zrób to jeszcze raz, tym razem zmieniając kolumnę na
PERSISTED
:I widzę, że dzieje się wręcz przeciwnie: dostaję wykonanie zalogowane na wstawce, ale nie na zaznaczeniu.
Nie masz wystarczająco nowoczesnej wersji programu SQL Server
sys.dm_exec_function_stats
? Bez obaw, jest to również ujęte w planach wykonania .W przypadku wersji nietrwałej widzimy funkcję, do której odwołuje się tylko w select:
Podczas gdy wersja utrwalona pokazuje tylko obliczenia wykonywane na wstawce:
Teraz Martin porusza świetny punkt w komentarzu : nie zawsze tak będzie. Utwórzmy indeks, który nie obejmuje utrwalonej kolumny obliczeniowej, i uruchommy kwerendę, która korzysta z tego indeksu, i zobaczmy, czy wyszukiwanie pobiera dane z istniejących utrwalonych danych, czy oblicza dane w czasie wykonywania (upuść i ponownie utwórz funkcję i stolik tutaj):
Teraz uruchomimy kwerendę, która korzysta z indeksu (tak czy inaczej domyślnie używa indeksu w tym konkretnym przypadku, nawet bez klauzuli where):
Widzę dodatkowe wykonania w statystykach funkcji, a plan nie leży:
Tak więc odpowiedź brzmi: TO ZALEŻY . W takim przypadku SQL Server uznał, że taniej będzie ponownie obliczyć wartości, niż przeprowadzić wyszukiwanie. To może się zmienić z powodu różnych czynników, więc nie polegaj na tym. Może się to zdarzyć w obu kierunkach, niezależnie od tego, czy używana jest funkcja zdefiniowana przez użytkownika; Użyłem go tylko tutaj, ponieważ znacznie ułatwiło to zilustrowanie.
źródło
Odpowiedź na to pytanie naprawdę brzmi „to zależy”. Właśnie natknąłem się na przykład, w którym SQL Server używa indeksu w utrwalonej kolumnie obliczeniowej, ale nadal wykonuje tę funkcję, tak jakby wartości nigdy nie były utrwalane na początku. Może to mieć związek z typem danych kolumny (
nvarchar(37)
) lub ewentualnie wielkością tabeli (około 7 milionów wierszy), ale SQL Server postanowił zignorowaćpersisted
słowo kluczowe, jak się wydaje, w tym konkretnym przypadku.W tym przypadku kluczem podstawowym w tabeli jest TransactionID, który jest również obliczoną i utrwaloną kolumną. Plan wykonania generuje skanowanie indeksu iw tabeli zawierającej tylko 7 milionów wierszy uruchomienie tego prostego zapytania zajmuje 2-3 minuty, ponieważ funkcja jest uruchamiana ponownie w każdym wierszu, a wartości nie wydają się być utrwalane w indeks.
źródło