Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Функция с стойност на таблица с множество изрази срещу функция с стойност на вградена таблица

Проучвайки коментара на Мат, преразгледах първоначалното си изявление. Той е прав, ще има разлика в производителността между функция с вградена таблица с стойност (ITVF) и функция с стойност на таблица с множество оператори (MSTVF), дори ако и двете просто изпълняват оператор SELECT. SQL Server ще третира ITVF донякъде като VIEW в това, че ще изчисли план за изпълнение, използвайки последните статистически данни за въпросните таблици. MSTVF е еквивалентен на пълнене на цялото съдържание на вашия оператор SELECT в таблична променлива и след това присъединяване към нея. По този начин компилаторът не може да използва никакви статистически данни за таблиците в MSTVF. Така че, при равни условия (което рядко са), ITVF ще се представи по-добре от MSTVF. При моите тестове разликата в производителността във времето за завършване беше незначителна, но от гледна точка на статистиката беше забележима.

Във вашия случай двете функции не са функционално еквивалентни. Функцията MSTV прави допълнителна заявка всеки път, когато е извикана и, най-важното, филтрира идентификатора на клиента. При голяма заявка оптимизаторът няма да може да се възползва от други типове обединения, тъй като ще трябва да извика функцията за всеки предаден customerId. Въпреки това, ако сте пренаписали функцията си MSTV така:

CREATE FUNCTION MyNS.GetLastShipped()
RETURNS @CustomerOrder TABLE
    (
    SaleOrderID    INT         NOT NULL,
    CustomerID      INT         NOT NULL,
    OrderDate       DATETIME    NOT NULL,
    OrderQty        INT         NOT NULL
    )
AS
BEGIN
    INSERT @CustomerOrder
    SELECT a.SalesOrderID, a.CustomerID, a.OrderDate, b.OrderQty
    FROM Sales.SalesOrderHeader a 
        INNER JOIN Sales.SalesOrderHeader b
            ON a.SalesOrderID = b.SalesOrderID
        INNER JOIN Production.Product c 
            ON b.ProductID = c.ProductID
    WHERE a.OrderDate = (
                        Select Max(SH1.OrderDate)
                        FROM Sales.SalesOrderHeader As SH1
                        WHERE SH1.CustomerID = A.CustomerId
                        )
    RETURN
END
GO

В заявка оптимизаторът ще може да извика тази функция веднъж и да изгради по-добър план за изпълнение, но все пак няма да бъде по-добър от еквивалентен, непараметризиран ITVS или VIEW .

ITVF трябва да се предпочитат пред MSTVF, когато е осъществимо, тъй като типовете данни, възможността за нулиране и съпоставянето от колоните в таблицата, докато декларирате тези свойства във функция с стойност на таблица с множество изрази и, което е важно, ще получите по-добри планове за изпълнение от ITVF. Според моя опит не открих много обстоятелства, при които ITVF е по-добър вариант от VIEW, но пробегът може да варира.

Благодаря на Мат.

Допълнение

Тъй като видях това да се появи наскоро, ето един отличен анализ, направен от Уейн Шефилд, сравняващ разликата в производителността между функциите с стойности на вградена таблица и функциите с множество изявления.

Оригиналната му публикация в блога.

Копирайте в SQL Server Central



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да използвате шаблони в SQL Server Management Studio (SSMS) - SQL Server / TSQL урок, част 16

  2. Най-добрите подходи за текущи суми – актуализиран за SQL Server 2012

  3. SQUARE() Примери в SQL Server

  4. Как да търся низ в база данни на SQL Server?

  5. Дилема за именуване на таблица:имена в единствено число срещу множествено число