В чем разница между функциями, возвращающими табличное значение, и представлениями? Есть ли что-то, что вы можете сделать с одним, что трудно или невозможно сделать с другим? Или разница в эффективности?
Ответы:
Встроенный TVF без параметров и нематериализованный View очень похожи. Ниже приведены некоторые функциональные отличия, которые приходят на ум.
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
Во время выполнения представления и встроенные TVF встроены и обрабатываются аналогично производным таблицам или CTE. Они могут не оцениваться полностью (или даже вообще в некоторых случаях) или могут оцениваться несколько раз в других . Многопозиционные TVF всегда будут оцениваться и сохраняться в типе возвращаемой таблицы (в основном в табличной переменной)
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
иVIEW_METADATA
У меня обычно есть эмпирическое правило, когда дело доходит до решения, преобразовывать ли my SELECT
в a VIEW
или a TVF
.
Для завершения просмотра требуется больше 2 секунд и более 10 000 записей? Если ДА, превратите его в TVF. Если нет, оставьте это в покое.
Конечно, правило основано исключительно на производительности .
С TVF я могу использовать CROSS APPLY
, например, чтобы рассматривать его как таблицу, но передавая определенное значение, такое как первичный ключ .
WHERE ID = xxx
, где «xxx» - это значение, которое я передаю в SELECT.
Производительность намного быстрее!
Если бы у меня было представление о TVF, мне пришлось бы позволить представлению возвращать более 2 миллионов строк, чтобы вернуть менее 1% от них в моих SELECT.
Что-то думать о.
Я обнаружил, что соединения с MultiStatement TVF работают намного лучше, чем Views, когда PK указан в таблице возврата функции.
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
предложением, не должна создавать никаких временных таблиц, поэтому она будет работать как минимум в два раза быстрее. Возможно, намного быстрее, поскольку оптимизатор сможет включить свой запрос в оптимизацию
Is Updatable
?