Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

फ़ंक्शन के साथ बाहरी आवेदन का प्रदर्शन

यह फ़ंक्शन प्रकार पर निर्भर करता है:

  1. यदि फ़ंक्शन एक इनलाइन तालिका-मूल्यवान फ़ंक्शन है तो इस फ़ंक्शन को "पैरामीटरयुक्त" दृश्य और SQL Server माना जाएगा कुछ अनुकूलन कार्य कर सकते हैं।

  2. यदि फ़ंक्शन बहु-चरण तालिका-मूल्यवान फ़ंक्शन है तो SQL Server . के लिए कठिन है SET STATISTICS IO . से स्टेटमेंट और आउटपुट को ऑप्टिमाइज़ करने के लिए भ्रामक होगा।

अगले परीक्षण के लिए मैंने AdventureWorks2008 . का उपयोग किया (आप इस डेटाबेस को कोडप्लेक्स से डाउनलोड कर सकते हैं)। इस नमूना डेटाबेस में आपको एक inline table-valued function मिल सकता है नाम [Sales].[ufnGetCheapestProduct] :

ALTER FUNCTION [Sales].[ufnGetCheapestProduct](@ProductID INT)
RETURNS TABLE
AS
RETURN
    SELECT   dt.ProductID
            ,dt.UnitPrice
    FROM
    (
        SELECT   d.SalesOrderDetailID
                ,d.UnitPrice
                ,d.ProductID  
                ,ROW_NUMBER() OVER(PARTITION BY d.ProductID ORDER BY d.UnitPrice ASC, d.SalesOrderDetailID) RowNumber
        FROM    Sales.SalesOrderDetail d
        WHERE   d.ProductID = @ProductID
    ) dt
    WHERE   dt.RowNumber = 1

मैंने [Sales].[ufnGetCheapestProductMultiStep] नाम से एक नया फ़ंक्शन बनाया है . यह फ़ंक्शन एक multi-step table-valued function है :

CREATE FUNCTION [Sales].[ufnGetCheapestProductMultiStep](@ProductID INT)
RETURNS @Results TABLE (ProductID INT PRIMARY KEY, UnitPrice MONEY NOT NULL)
AS
BEGIN
    INSERT  @Results(ProductID, UnitPrice)
    SELECT   dt.ProductID
            ,dt.UnitPrice
    FROM
    (
        SELECT   d.SalesOrderDetailID
                ,d.UnitPrice
                ,d.ProductID  
                ,ROW_NUMBER() OVER(PARTITION BY d.ProductID ORDER BY d.UnitPrice ASC, d.SalesOrderDetailID) RowNumber
        FROM    Sales.SalesOrderDetail d
        WHERE   d.ProductID = @ProductID
    ) dt
    WHERE   dt.RowNumber = 1;

    RETURN;
END

अब, हम अगले परीक्षण चला सकते हैं:

--Test 1
SELECT  p.ProductID, p.Name, oa1.*
FROM    Production.Product p
OUTER APPLY 
(
    SELECT   dt.ProductID
            ,dt.UnitPrice
    FROM
    (
        SELECT   d.SalesOrderDetailID
                ,d.UnitPrice
                ,d.ProductID  
                ,ROW_NUMBER() OVER(PARTITION BY d.ProductID ORDER BY d.UnitPrice ASC, d.SalesOrderDetailID) RowNumber
        FROM    Sales.SalesOrderDetail d
        WHERE   d.ProductID = p.ProductID
    ) dt
    WHERE   dt.RowNumber = 1
) oa1

--Test 2
SELECT  p.ProductID, p.Name, oa2.*
FROM    Production.Product p
OUTER APPLY [Sales].[ufnGetCheapestProduct](p.ProductID) oa2

--Test 3
SELECT  p.ProductID, p.Name, oa3.*
FROM    Production.Product p
OUTER APPLY [Sales].[ufnGetCheapestProductMultiStep](p.ProductID) oa3

और यह SQL Profiler का आउटपुट है :

निष्कर्ष :आप देख सकते हैं कि OUTER APPLY के साथ किसी क्वेरी या इनलाइन तालिका-मूल्यवान फ़ंक्शन का उपयोग करना आपको वही प्रदर्शन देगा (तार्किक पढ़ता है)। प्लस:बहु-चरण तालिका-मूल्यवान फ़ंक्शन (आमतौर पर) अधिक महंगे होते हैं

नोट :मैं SET STATISTICS IO . का उपयोग करने की अनुशंसा नहीं करता हूं IO . को मापने के लिए अदिश और बहु-चरण तालिका के लिए मूल्यवान फ़ंक्शन क्योंकि परिणाम गलत हो सकते हैं। उदाहरण के लिए, इन परीक्षणों के लिए SET STATISTICS IO ON . से आउटपुट होगा:

--Test 1
Table 'SalesOrderDetail'. Scan count 504, logical reads 1513, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Product'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

--Test 2
Table 'SalesOrderDetail'. Scan count 504, logical reads 1513, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Product'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

--Test 3
Table '#064EAD61'. Scan count 504, logical reads 1008 /*WRONG*/, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Product'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कैसे ठीक करें "प्रक्रिया को 'ntext/nchar/nvarchar' प्रकार के पैरामीटर '@statement' की अपेक्षा है।" SQL सर्वर में त्रुटि

  2. गणना किए गए कॉलम कब उपयुक्त होते हैं?

  3. SQL सर्वर इंस्टेंस के सभी डेटाबेस में प्राथमिक कुंजी बाधा के बिना तालिकाओं की सूची कैसे प्राप्त करें - SQL सर्वर / TSQL ट्यूटोरियल भाग 62

  4. मामला जब खंड द्वारा आदेश के लिए बयान

  5. दो स्तंभों के संयोजन के लिए अद्वितीय बाधा जोड़ें