Was ist der Unterschied zwischen Funktionen und Ansichten mit Tabellenwerten? Gibt es etwas, das Sie mit einem tun können, das mit dem anderen schwer oder unmöglich zu tun ist? Oder liegt der Unterschied in der Effizienz?
Antworten:
Eine parameterlose Inline-TVF und eine nicht materialisierte Ansicht sind sehr ähnlich. Einige funktionale Unterschiede, die mir in den Sinn kommen, sind unten aufgeführt.
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
Zur Laufzeit werden Ansichten und Inline-TVFs inline dargestellt und ähnlich wie abgeleitete Tabellen oder CTEs behandelt. Sie werden möglicherweise nicht vollständig (oder in einigen Fällen überhaupt) oder in anderen Fällen mehrmals bewertet . Multistatement-TVFs werden immer ausgewertet und im Rückgabetabellentyp gespeichert (im Grunde eine Tabellenvariable).
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
undVIEW_METADATA
Ich habe im Allgemeinen eine Faustregel, wenn es darum geht, zu entscheiden, ob ich meine SELECT
in eine VIEW
oder eine umwandeln möchte TVF
.
Dauert die Ansicht länger als 2 Sekunden und verfügt sie über mehr als 10.000 Datensätze? Wenn JA, verwandeln Sie es in einen TVF. Wenn nicht, lass es in Ruhe.
Natürlich basiert die Regel nur auf der Leistung .
Mit einer TVF kann ich CROSS APPLY
beispielsweise eine als Tabelle behandeln, aber einen bestimmten Wert übergeben, z. B. den Primärschlüssel .
WHERE ID = xxx
, wobei 'xxx' der Wert ist, den ich in SELECT übergebe.
Leistung ist viel schneller!
Wenn ich eine Ansicht der TVF hätte, müsste ich zulassen, dass die Ansicht mehr als 2 Millionen Zeilen zurückbringt, um weniger als 1% davon in meinen SELECTs zurückzugeben.
Etwas zum Nachdenken.
Ich habe festgestellt, dass Verknüpfungen mit MultiStatement-TVFs eine viel bessere Leistung aufweisen als Ansichten, wenn in der Rückgabetabelle der Funktion eine PK angegeben ist.
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
Klausel, muss keine temporären Tabellen erstellen, sodass sie mindestens doppelt so schnell ausgeführt wird. Möglicherweise viel schneller, da der Optimierer seine Abfrage in die Optimierung
Is Updatable
?