Яка різниця між функціями, що мають значення таблиці, та поданнями? Чи є щось, що ви можете зробити з 1, що важко чи неможливо зробити з іншим? Або різниця полягає в ефективності?
Відповіді:
Вбудований TVF без параметрів і нематеріалізований вигляд дуже схожі. Нижче наведено кілька функціональних відмінностей.
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
Як правило, у мене є правило, коли потрібно вирішувати, перетворювати мій SELECT
на a VIEW
або a TVF
.
Чи займає подання більше 2 секунд, і чи містить у ньому більше 10000 записів? Якщо ТАК, перетворіть його на 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
?