Funkcja z wartościami tabelarycznymi (TVF) a widok

83

Jaka jest różnica między funkcjami wycenionymi w tabeli a widokami? Czy jest coś, co możesz zrobić z jednym, co jest trudne lub niemożliwe do zrobienia z drugim? A może różnica polega na wydajności?

Haoest
źródło

Odpowiedzi:

136

Bezparametrowe wbudowane TVF i niezmaterializowany widok są bardzo podobne. Poniżej przedstawiono kilka funkcjonalnych różnic, które przychodzą na myśl.

Wyświetlenia

Accepts Parameters               - No
Expanded out by Optimiser        - Yes
Can be Materialized in advance   - Yes (through indexed views)
Is Updatable                     - Yes 
Can contain Multiple Statements  - No
Can have triggers                - Yes
Can use side-effecting operator  - Yes  

Inline TVFs

Accepts Parameters               - Yes
Expanded out by Optimiser        - Yes
Can be Materialized in advance   - No
Is Updatable                     - Yes
Can contain Multiple Statements  - No
Can have triggers                - No
Can use side-effecting operator  - No    

MultiStatement TVFs

Accepts Parameters               - Yes
Expanded out by Optimiser        - No
Can be Materialized in advance   - No
Is Updatable                     - No
Can contain Multiple Statements  - Yes
Can have triggers                - No
Can use side-effecting operator  - No    

W czasie wykonywania widoki i wbudowane funkcje TVF są zarówno wstawiane, jak i traktowane podobnie do tabel pochodnych lub CTE. Mogą nie zostać ocenione w całości (lub nawet w ogóle w niektórych przypadkach), aw innych mogą być oceniane wielokrotnie . Wielostanowiskowe TVF będą zawsze oceniane i przechowywane w typie tabeli zwracanej (w zasadzie zmienna tabeli)

Czasami możliwość bezpośredniego sparametryzowania wbudowanych funkcji TVF może prowadzić do lepszego planu wykonania niż równoważne sparametryzowane zapytanie względem widoku.

Martin Smith
źródło
3
co masz na myśli tvf Is Updatable?
Royi Namir
2
@RoyiNamir - wbudowany TVF może służyć do aktualizacji tabeli bazowej podobnie do widoku.
Martin Smith
czy masz na myśli, że TVF może zaktualizować tabelę zwrotną od siebie?
Royi Namir
12
@RoyiNamir - PrzykładCREATE TABLE T(C INT);EXEC('CREATE FUNCTION F () RETURNS TABLE AS RETURN (SELECT * FROM T)');INSERT INTO F() VALUES(1);SELECT * FROM T;
Martin Smith
Kilka innych różnic with check optioniVIEW_METADATA
Martin Smith
5

Generalnie mam praktyczną zasadę, jeśli chodzi o podjęcie decyzji, czy przekonwertować SELECTplik my na a VIEWlub a TVF.

Czy wyświetlanie trwa dłużej niż 2 sekundy i czy zawiera ponad 10 000 rekordów? Jeśli TAK, zmień go w TVF. Jeśli nie, zostaw to w spokoju.

Oczywiście zasada opiera się wyłącznie na wydajności .

Z TVF mogę użyć CROSS APPLY, na przykład, aby traktować go jako tabelę, ale przekazując określoną wartość, taką jak klucz podstawowy .

WHERE ID = xxx, gdzie „xxx” to wartość, którą przekazuję w SELECT.

Wydajność jest znacznie szybsza!

Gdybym miał widok TVF, musiałbym pozwolić, aby widok przywrócił ponad 2 miliony wierszy tylko po to, aby zwrócić mniej niż 1% tego w moich SELECT.

Coś do przemyślenia.

Fandango68
źródło
2

Zauważyłem, że sprzężenia z MultiStatement TVF działają znacznie lepiej niż Widoki, gdy PK jest określona w tabeli zwrotów funkcji.

CREATE FUNCTION [FORMREQS].[fnGetFormsStatus] ()
RETURNS

/* Create a PK using two of the columns */
@Indexed TABLE (
    [OrgID] [char](8) NOT NULL,
    [PkgID] [int] NOT NULL,
    [FormID] varchar(5) NOT NULL,
    PRIMARY KEY CLUSTERED(OrgID, PkgID) 
)
AS
BEGIN
INSERT @Indexed SELECT OrgID, PkgID, FormID FROM FormsTable

RETURN

END
Douglas
źródło
1
Widoki też. W rzeczywistości tworzenie tabeli skutkuje znacznie wolniejszą funkcją. Funkcja inline, tj. Taka z pojedynczą RETURNSklauzulą, nie musiałaby tworzyć żadnych tabel tymczasowych, więc działałaby co najmniej dwa razy szybciej. Prawdopodobnie dużo szybciej, ponieważ optymalizator byłby w stanie uwzględnić swoje zapytanie w optymalizacji
Panagiotis Kanavos