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?
Odpowiedzi:
Bezparametrowe wbudowane TVF i niezmaterializowany widok są bardzo podobne. Poniżej przedstawiono kilka funkcjonalnych różnic, które przychodzą na myśl.
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
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
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)
CREATE TABLE T(C INT);EXEC('CREATE FUNCTION F () RETURNS TABLE AS RETURN (SELECT * FROM T)');INSERT INTO F() VALUES(1);SELECT * FROM T;
with check option
iVIEW_METADATA
Generalnie mam praktyczną zasadę, jeśli chodzi o podjęcie decyzji, czy przekonwertować SELECT
plik my na a VIEW
lub 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.
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
RETURNS
klauzulą, 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
Is Updatable
?