เหตุใดแบบสอบถามนี้จึงช้าลงอย่างมากเมื่อรวมไว้ใน TVF


17

ฉันมีคิวรีที่ค่อนข้างซับซ้อนซึ่งทำงานในเวลาเพียงไม่กี่วินาทีด้วยตัวเอง แต่เมื่อรวมกับฟังก์ชันที่มีค่าเป็นตารางมันจะช้ากว่ามาก ฉันไม่ได้ปล่อยให้มันจบ แต่มันวิ่งไปสิบนาทีโดยไม่จบ การเปลี่ยนแปลงเพียงอย่างเดียวคือการแทนที่ตัวแปรวันที่สองตัว (เริ่มต้นด้วยตัวอักษรวันที่) ด้วยพารามิเตอร์วันที่:

ทำงานในเจ็ดวินาที

DECLARE @StartDate DATE = '2011-05-21'
DECLARE @EndDate   DATE = '2011-05-23'

DECLARE @Data TABLE (...)
INSERT INTO @Data(...) SELECT...

SELECT * FROM @Data

ทำงานอย่างน้อยสิบนาที

CREATE FUNCTION X (@StartDate DATE, @EndDate DATE)
  RETURNS TABLE AS RETURN
  SELECT ...

SELECT * FROM X ('2011-05-21', '2011-05-23')

ก่อนหน้านี้ฉันได้เขียนฟังก์ชั่นเป็นคำสั่ง TVF แบบหลายประโยคพร้อมกับประโยค RETURNS @Data TABLE (... ) แต่การสลับที่โครงสร้างอินไลน์ไม่ได้ทำให้เกิดการเปลี่ยนแปลงที่เห็นได้ชัดเจน เวลาที่ยาวนานของ TVF เป็นSELECT * FROM Xเวลาจริง จริงๆแล้วการสร้าง UDF ใช้เวลาเพียงไม่กี่วินาที

ฉันสามารถโพสต์คำถามที่สงสัย แต่มันยาวไปหน่อย (~ 165 บรรทัด) และจากความสำเร็จของวิธีแรกฉันสงสัยว่ามีบางอย่างเกิดขึ้น การอ่านแบบแผนการดำเนินการต่าง ๆ ดูเหมือนว่าจะเหมือนกัน

ฉันพยายามแบ่งแบบสอบถามเป็นส่วนเล็ก ๆ โดยไม่มีการเปลี่ยนแปลง ไม่มีส่วนใดที่ใช้เวลามากกว่าสองสามวินาทีเมื่อดำเนินการเพียงอย่างเดียว แต่ TVF ยังคงค้าง

ฉันเห็นคำถามที่คล้ายกันมาก/programming/4190506/sql-server-2005-table-valued-function-weird-performanceแต่ฉันไม่แน่ใจว่าจะใช้วิธีแก้ปัญหานี้หรือไม่ บางทีใครบางคนได้เห็นปัญหานี้และรู้วิธีแก้ปัญหาทั่วไปเพิ่มเติมหรือไม่ ขอบคุณ!

นี่คือ dm_exec_requests หลังจากประมวลผลหลายนาที:

session_id              59
request_id              0
start_time              40688.46517
status                  running
command                 UPDATE
sql_handle              0x030015002D21AF39242A1101ED9E00000000000000000000
statement_start_offset  10962
statement_end_offset    16012
plan_handle             0x050015002D21AF3940C1E6B0040000000000000000000000
database_id                 21
user_id                 1
connection_id           314AE0E4-A1FB-4602-BF40-02D857BAD6CF
blocking_session_id         0
wait_type               NULL
wait_time                   0
last_wait_type          SOS_SCHEDULER_YIELD
wait_resource   
open_transaction_count  0
open_resultset_count    1
transaction_id              48030651
context_info            0x
percent_complete        0
estimated_completion_time   0
cpu_time                    344777
total_elapsed_time          348632
scheduler_id            7
task_address            0x000000045FC85048
reads                   1549
writes                  13
logical_reads           30331425
text_size               2147483647
language                us_english
date_format             mdy
date_first              7
quoted_identifier           1
arithabort              1
ansi_null_dflt_on       1
ansi_defaults           0
ansi_warnings           1
ansi_padding            1
ansi_nulls                  1
concat_null_yields_null 1
transaction_isolation_level 2
lock_timeout            -1
deadlock_priority           0
row_count                   105
prev_error              0
nest_level              1
granted_query_memory    170
executing_managed_code  0
group_id                2
query_hash              0xBE6A286546AF62FC
query_plan_hash         0xD07630B947043AF0

นี่คือแบบสอบถามที่สมบูรณ์:

CREATE FUNCTION Routine.MarketingDashboardECommerceBase (@StartDate DATE, @EndDate DATE)
RETURNS TABLE AS RETURN
    WITH RegionsByCode AS (SELECT CountryCode, MIN(Region) AS Region FROM Staging.Volusion.MarketingRegions GROUP BY CountryCode)
        SELECT
            D.Date, Div.Division, Region.Region, C.Category1, C.Category2, C.Category3,
            COALESCE(V.Visits,          0) AS Visits,
            COALESCE(Dem.Demos,         0) AS Demos,
            COALESCE(S.GrossStores,     0) AS GrossStores,
            COALESCE(S.PaidStores,      0) AS PaidStores,
            COALESCE(S.NetStores,       0) AS NetStores,
            COALESCE(S.StoresActiveNow, 0) AS StoresActiveNow
            -- This line causes the run time to climb from a few seconds to over an hour!
            --COALESCE(V.Visits,          0) * COALESCE(ACS.AvgClickCost, GAAC.AvgAdCost, 0.00) AS TotalAdCost
            -- This line alone does not inflate the run time
            --ACS.AvgClickCost
            -- This line is enough to increase the run time to at least a couple minutes
            --GAAC.AvgAdCost
        FROM
            --Dates AS D
            (SELECT SQLDate AS Date FROM Dates WHERE SQLDate BETWEEN @StartDate AND @EndDate) AS D
            CROSS JOIN (SELECT 'UK' AS Division UNION SELECT 'US' UNION SELECT 'IN' UNION SELECT 'Unknown') AS Div
            CROSS JOIN (SELECT Category1, Category2, Category3 FROM Routine.MarketingDashboardCampaignMap UNION SELECT 'Unknown', 'Unknown', 'Unknown') AS C
            CROSS JOIN (SELECT DISTINCT Region FROM Staging.Volusion.MarketingRegions) AS Region
            -- Visitors
            LEFT JOIN
                (
                SELECT
                    V.Date,
                    CASE    WHEN V.Country IN ('United Kingdom', 'Guernsey', 'Ireland', 'Jersey') THEN 'UK'
                        WHEN V.Country IN ('United States', 'Canada', 'Puerto Rico', 'U.S. Virgin Islands') THEN 'US'
                        ELSE 'IN' END AS Division,
                    COALESCE(MR.Region, 'Unknown') AS Region,
                    C.Category1, C.Category2, C.Category3,
                    SUM(V.Visits) AS Visits
                FROM
                             RawData.GoogleAnalytics.Visits        AS V
                    INNER JOIN Routine.MarketingDashboardCampaignMap AS C ON V.LandingPage = C.LandingPage AND V.Campaign = C.Campaign AND V.Medium = C.Medium AND V.Referrer = C.Referrer AND V.Source = C.Source
                    LEFT JOIN  Staging.Volusion.MarketingRegions     AS MR ON V.Country = MR.CountryName
                WHERE
                    V.Date BETWEEN @StartDate AND @EndDate
                GROUP BY
                    V.Date,
                    CASE    WHEN V.Country IN ('United Kingdom', 'Guernsey', 'Ireland', 'Jersey') THEN 'UK'
                        WHEN V.Country IN ('United States', 'Canada', 'Puerto Rico', 'U.S. Virgin Islands') THEN 'US'
                        ELSE 'IN' END,
                    COALESCE(MR.Region, 'Unknown'), C.Category1, C.Category2, C.Category3
                ) AS V ON D.Date = V.Date AND Div.Division = V.Division AND Region.Region = V.Region AND C.Category1 = V.Category1 AND C.Category2 = V.Category2 AND C.Category3 = V.Category3
            -- Demos
            LEFT JOIN
                (
                SELECT
                    OD.SQLDate,
                    G.Division,
                    COALESCE(MR.Region,   'Unknown') AS Region,
                    COALESCE(C.Category1, 'Unknown') AS Category1,
                    COALESCE(C.Category2, 'Unknown') AS Category2,
                    COALESCE(C.Category3, 'Unknown') AS Category3,
                    SUM(D.Demos) AS Demos
                FROM
                             Demos            AS D
                    INNER JOIN Orders           AS O  ON D."Order" = O."Order"
                    INNER JOIN Dates            AS OD ON O.OrderDate = OD.DateSerial
                    INNER JOIN MarketingSources AS MS ON D.Source = MS.Source
                    LEFT JOIN  RegionsByCode    AS MR ON MS.CountryCode = MR.CountryCode
                    LEFT JOIN
                        (
                        SELECT
                            G.TransactionID,
                            MIN (
                                CASE WHEN G.Country IN ('United Kingdom', 'Guernsey', 'Ireland', 'Jersey') THEN 'UK'
                                    WHEN G.Country IN ('United States', 'Canada', 'Puerto Rico', 'U.S. Virgin Islands') THEN 'US'
                                    ELSE 'IN' END
                                ) AS Division
                        FROM
                            RawData.GoogleAnalytics.Geography AS G
                        WHERE
                                TransactionDate BETWEEN @StartDate AND @EndDate
                            AND NOT EXISTS (SELECT * FROM RawData.GoogleAnalytics.Geography AS G2 WHERE G.TransactionID = G2.TransactionID AND G2.EffectiveDate > G.EffectiveDate)
                        GROUP BY
                            G.TransactionID
                        ) AS G  ON O.VolusionOrderID = G.TransactionID
                    LEFT JOIN  RawData.GoogleAnalytics.Referrers     AS R  ON O.VolusionOrderID = R.TransactionID AND NOT EXISTS (SELECT * FROM RawData.GoogleAnalytics.Referrers AS R2 WHERE R.TransactionID = R2.TransactionID AND R2.EffectiveDate > R.EffectiveDate)
                    LEFT JOIN  Routine.MarketingDashboardCampaignMap AS C  ON MS.LandingPage = C.LandingPage AND MS.Campaign = C.Campaign AND MS.Medium = C.Medium AND COALESCE(R.ReferralPath, '(not set)') = C.Referrer AND MS.SourceName = C.Source
                WHERE
                        O.IsDeleted = 'No'
                    AND OD.SQLDate BETWEEN @StartDate AND @EndDate
                GROUP BY
                    OD.SQLDate,
                    G.Division,
                    COALESCE(MR.Region,   'Unknown'),
                    COALESCE(C.Category1, 'Unknown'),
                    COALESCE(C.Category2, 'Unknown'),
                    COALESCE(C.Category3, 'Unknown')
                ) AS Dem ON D.Date = Dem.SQLDate AND Div.Division = Dem.Division AND Region.Region = Dem.Region AND C.Category1 = Dem.Category1 AND C.Category2 = Dem.Category2 AND C.Category3 = Dem.Category3
            -- Stores
            LEFT JOIN
                (
                SELECT
                    OD.SQLDate,
                    CASE WHEN O.VolusionCountryCode = 'GB' THEN 'UK'
                        WHEN A.CountryShortName IN ('U.S.', 'Canada', 'Puerto Rico', 'U.S. Virgin Islands') THEN 'US'
                        ELSE 'IN' END AS Division,
                    COALESCE(MR.Region,     'Unknown') AS Region,
                    COALESCE(CpM.Category1, 'Unknown') AS Category1,
                    COALESCE(CpM.Category2, 'Unknown') AS Category2,
                    COALESCE(CpM.Category3, 'Unknown') AS Category3,
                    SUM(S.Stores) AS GrossStores,
                    SUM(CASE WHEN O.DatePaid <> -1 THEN 1 ELSE 0 END) AS PaidStores,
                    SUM(CASE WHEN O.DatePaid <> -1 AND CD.WeekEnding <> OD.WeekEnding THEN 1 ELSE 0 END) AS NetStores,
                    SUM(CASE WHEN O.DatePaid <> -1 THEN SH.ActiveStores ELSE 0 END) AS StoresActiveNow
                FROM
                             Stores           AS S
                    INNER JOIN Orders           AS O   ON S."Order" = O."Order"
                    INNER JOIN Dates            AS OD  ON O.OrderDate = OD.DateSerial
                    INNER JOIN Dates            AS CD  ON O.CancellationDate = CD.DateSerial
                    INNER JOIN Customers        AS C   ON O.CustomerNow = C.Customer
                    INNER JOIN MarketingSources AS MS  ON C.Source = MS.Source
                    INNER JOIN StoreHistory     AS SH  ON S.MostRecentHistory = SH.History
                    INNER JOIN Addresses        AS A   ON C.Address = A.Address
                    LEFT JOIN  RegionsByCode    AS MR  ON MS.CountryCode = MR.CountryCode
                    LEFT JOIN  Routine.MarketingDashboardCampaignMap AS CpM ON CpM.LandingPage = 'N/A' AND MS.Campaign = CpM.Campaign AND MS.Medium = CpM.Medium AND CpM.Referrer = 'N/A' AND MS.SourceName = CpM.Source
                WHERE
                        O.IsDeleted = 'No'
                    AND OD.SQLDate BETWEEN @StartDate AND @EndDate
                GROUP BY
                    OD.SQLDate,
                    CASE WHEN O.VolusionCountryCode = 'GB' THEN 'UK'
                        WHEN A.CountryShortName IN ('U.S.', 'Canada', 'Puerto Rico', 'U.S. Virgin Islands') THEN 'US'
                        ELSE 'IN' END,
                    COALESCE(MR.Region,     'Unknown'),
                    COALESCE(CpM.Category1, 'Unknown'),
                    COALESCE(CpM.Category2, 'Unknown'),
                    COALESCE(CpM.Category3, 'Unknown')
                ) AS S ON D.Date = S.SQLDate AND Div.Division = S.Division AND Region.Region = S.Region AND C.Category1 = S.Category1 AND C.Category2 = S.Category2 AND C.Category3 = S.Category3
            -- Google Analytics spend
            LEFT JOIN
                (
                SELECT
                    AC.Date, C.Category1, C.Category2, C.Category3, SUM(AC.AdCost) / SUM(AC.Visits) AS AvgAdCost
                FROM
                    RawData.GoogleAnalytics.AdCosts AS AC
                    INNER JOIN
                        (
                        SELECT Campaign, Medium, Source, MIN(Category1) AS Category1, MIN(Category2) AS Category2, MIN(Category3) AS Category3
                        FROM Routine.MarketingDashboardCampaignMap
                        WHERE Category1 <> 'Affiliate'
                        GROUP BY Campaign, Medium, Source
                        ) AS C ON AC.Campaign = C.Campaign AND AC.Medium = C.Medium AND AC.Source = C.Source
                WHERE
                    AC.Date BETWEEN @StartDate AND @EndDate
                GROUP BY
                    AC.Date, C.Category1, C.Category2, C.Category3
                HAVING
                    SUM(AC.AdCost) > 0.00 AND SUM(AC.Visits) > 0
                ) AS GAAC ON D.Date = GAAC.Date AND C.Category1 = GAAC.Category1 AND C.Category2 = GAAC.Category2 AND C.Category3 = GAAC.Category3
            -- adCenter spend
            LEFT JOIN
                (
                SELECT Date, SUM(Spend) / SUM(Clicks) AS AvgClickCost
                FROM RawData.AdCenter.Spend
                WHERE Date BETWEEN @StartDate AND @EndDate
                GROUP BY Date
                HAVING SUM(Spend) > 0.00 AND SUM(Clicks) > 0
                ) AS ACS ON D.Date = ACS.Date AND C.Category1 = 'PPC' AND C.Category2 = 'adCenter' AND C.Category3 = 'N/A'
        WHERE
            V.Visits > 0 OR Dem.Demos > 0 OR S.GrossStores > 0
GO


SELECT * FROM Routine.MarketingDashboardECommerceBase('2011-05-21', '2011-05-23')

คุณช่วยแสดงแผนแบบสอบถามข้อความให้เราดูได้ไหม และในข้อความค้นหาแรกประเภทใดคือ @StartDate + @EndDate
gbn

@gbn: ขออภัยแผนยาวเกินไปที่ประมาณ 32K ตัวอักษร มีเซตย่อยที่จะมีประโยชน์มากที่สุดหรือไม่? นอกจากนี้คุณต้องการแผนสำหรับแบบสอบถามแบบสแตนด์อะโลนหรือ TVF หรือไม่
จอนแห่งการค้าทั้งหมด

การเรียกใช้แผนการดำเนินการในรูปแบบ TVF ของแบบสอบถามจะไม่มีข้อมูลที่เป็นประโยชน์ดังนั้นฉันคิดว่าคุณกำลังมองหาแผนแบบสอบถามสำหรับรุ่นที่ไม่ใช่ TVF หรือมีวิธีการบางอย่างในการวางแผนการใช้งานจริงโดย TVF?
จอนแห่งการค้าทั้งหมด

ไม่ต้องรองาน ฉันไม่คุ้นเคยกับ dm_exec_requests แต่ฉันได้ผนวกเอาท์พุทเป็นเครื่องหมายห้านาทีในการดำเนินการของ TVF
จอนแห่งการค้าทั้งหมด

@ มาร์ติน: ใช่; คิวรีแบบสแตนด์อโลนมีเวลา CPU ของ 7021 (2% ของTVF บางส่วน ) และการอ่านตรรกะ 154K (0.5%) ฉันเพิ่งออกจาก TVF เวอร์ชั่นเพื่อเรียกใช้และเสร็จหลังจาก 27 นาที ดังนั้นการปั่นผ่านข้อมูลมากขึ้นอย่างแน่นอน ... แต่ฉันจะทำให้มันใช้แผนการที่ดีกว่าได้อย่างไร ฉันจะศึกษารายละเอียดแผนการปฏิบัติงานที่ดีและดูว่ามีคำแนะนำเล็กน้อยช่วยไหม
Jon of All Trades

คำตอบ:


3

ฉันแยกปัญหาเป็นหนึ่งบรรทัดในแบบสอบถาม โปรดทราบว่าข้อความค้นหามีความยาว 160 บรรทัดและฉันรวมตารางที่เกี่ยวข้องด้วยวิธีใดถ้าฉันปิดใช้งานบรรทัดนี้จากส่วนคำสั่ง SELECT:

COALESCE(V.Visits, 0) * COALESCE(ACS.AvgClickCost, GAAC.AvgAdCost, 0.00)

... เวลารันไทม์ลดลงจาก 63 นาทีถึงห้าวินาที (การฝัง CTE ทำให้เร็วกว่าเคียวรีเจ็ดวินาทีเดิมเล็กน้อย) การรวมอย่างใดอย่างหนึ่งACS.AvgClickCostหรือGAAC.AvgAdCostเป็นสาเหตุให้เวลาที่ใช้ในการระเบิด สิ่งที่ทำให้มันแปลกโดยเฉพาะคือเขตข้อมูลเหล่านี้มาจากสองแบบสอบถามย่อยที่มีตามลำดับสิบแถวและสาม! พวกเขาแต่ละคนทำงานในศูนย์วินาทีเมื่อทำงานอย่างอิสระและด้วยการนับแถวนั้นสั้นมากฉันคาดว่าเวลาเข้าร่วมจะไม่สำคัญแม้จะใช้ลูปซ้อนกัน

มีการเดาว่าทำไมการคำนวณที่ดูไม่เป็นอันตรายนี้จะทำให้ TVF หายไปอย่างสมบูรณ์ในขณะที่มันทำงานได้อย่างรวดเร็วในฐานะที่เป็นแบบสอบถามแบบสแตนด์อะโลน


ฉันโพสต์คำถาม แต่อย่างที่คุณเห็นมันวาดบนโต๊ะโหลรวมถึงบางมุมมองและ TVF อื่น ๆ ดังนั้นฉันกลัวว่ามันจะไม่เป็นประโยชน์ ส่วนที่ฉันไม่เข้าใจคือวิธีการห่อแบบสอบถามใน TVF สามารถทวีคูณเวลารันด้วย 750 จะเกิดขึ้นก็ต่อเมื่อฉันรวมไว้GAAC.AvgAdCost(วันนี้เมื่อวานACS.AvgClickCostนี้เป็นปัญหาด้วย) ดังนั้นแบบสอบถามย่อยจึงดูเหมือนจะละทิ้งแผนการดำเนินการ .
Jon of All Trades

1
ฉันเดาว่าคุณต้องดูคำสั่งย่อยสำหรับการสืบค้นย่อย หากคุณได้รับความสัมพันธ์แบบหลายต่อหลายครั้งระหว่างตารางใด ๆ คุณจะได้รับการบันทึกมากกว่า 10 เท่า

เมื่อถึงจุดหนึ่งในโครงการของเรา (ซึ่งมีจำนวนการดูซ้อนกันและ TVF แบบอินไลน์) เราพบว่าตัวเองกำลังแทนที่COALESCE()ด้วยISNULL()เพื่อช่วยให้ร่างแผนเพิ่มประสิทธิภาพการสืบค้นดีขึ้น ฉันคิดว่ามันจะทำอย่างไรกับการมีประเภทของการส่งออกคาดการณ์มากขึ้นกว่าISNULL() COALESCE()คุ้มค่าที่จะลอง? ฉันรู้ว่านี่เป็นสิ่งที่คลุมเครือ แต่จากประสบการณ์ที่ จำกัด ของเราการมีอิทธิพลต่อเครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาเพื่อวางแผนที่ดีกว่าดูเหมือนว่าเป็นงานศิลปะที่คลุมเครือดังนั้นการลองใช้ความคิดบ้า ๆ

2

ฉันคาดหวังว่าสิ่งนี้เกี่ยวข้องกับการดมพารามิเตอร์

บางคนพูดถึงปัญหาอยู่ที่นี่ (และคุณสามารถค้นหา SO เพื่อดมกลิ่นพารามิเตอร์)

http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx


คุณไม่ได้รับการดมพารามิเตอร์ด้วย inline TVFs: มันเป็นเพียงมาโครที่ขยายออกเหมือนกับมุมมอง
gbn

@gbn: มันอาจจะเป็นจริงที่ตัว TVF นั้นถูกขยายเหมือนแมโคร แต่ (ตามที่ฉันเข้าใจ) เคียวรีหรือ sproc ที่เรียกใช้การขยายตัวในท้ายที่สุดนั้นขึ้นอยู่กับการวางแผนและการกำหนดพารามิเตอร์ที่เป็นไปได้ (เราต่อสู้กับสิ่งนี้ใน SQL Server 2005 มาระยะเวลาหนึ่งการต่อสู้นั้นยากเป็นพิเศษจนกระทั่งเราพบ SQL Server Management Studio โดยใช้การตั้งค่าเซสชันที่แตกต่างกัน ( ARITHABORTอาจจะ?) มากกว่า Reporting Services และ / หรือ jTDS ดังนั้นบางครั้งพวกเขา แผน "เลวร้าย" แต่คนอื่น ๆ (จะโกรธ) ทำโอเค "กับข้อความค้นหาเดียวกัน")

มันมีกลิ่นเหมือนการดมกลิ่นกับฉัน ....
โฮแกน

อืมอ่านมากต้องทำ สำหรับสิ่งที่คุ้มค่าไม่มีความแตกต่างอย่างมากในความสำคัญของค่าพารามิเตอร์: แบบสอบถามประกอบด้วยตารางวันที่มีแถวเดียวต่อวันและตารางอื่น ๆ หลายแห่งที่มีหลายแถวต่อวัน แต่เกี่ยวกับจำนวนเดียวกันสำหรับวันที่กำหนด ฉันใช้พารามิเตอร์เดียวกัน (05/21 ถึง 05/23) ในการดำเนินการทดสอบทันทีหลังจาก (สร้างใหม่) สร้าง UDF ดังนั้นหากมีสิ่งใดที่ควร "ลงสีพื้น" สำหรับค่าเหล่านั้น
จอนแห่งการค้าทั้งหมด

อีกหนึ่งหมายเหตุ: การกำหนดค่าของพารามิเตอร์ให้กับตัวแปรท้องถิ่นตามที่อธิบายโดย Jetson ในstackoverflow.com/questions/211355/…ไม่มีผลกระทบต่อวัสดุ
Jon of All Trades

1

น่าเสียดายที่เครื่องมือเพิ่มประสิทธิภาพการสืบค้นของ SQL ไม่สามารถมองเห็นฟังก์ชันภายในได้

ดังนั้นฉันจะใช้แผนการดำเนินการจากแผนด่วนเพื่อหาคำแนะนำในการใช้ TF ล้างและทำซ้ำจนกว่าแผนการดำเนินการของ TF จะเร็วกว่า

http://sqlblog.com/blogs/tibor_karaszi/archive/2008/08/29/execution-plan-re-use-sp-executesql-and-tsql-variables.aspx


2
เครื่องมือเพิ่มประสิทธิภาพการสืบค้น SQL Server สามารถมองเห็นภายในของ ITVF (ฟังก์ชั่นมูลค่าตารางแบบอินไลน์) แต่ไม่สามารถทำได้

หมายเหตุ: ฟังก์ชั่นตารางแบบอินไลน์พร้อมการใช้ข้ามเมื่อการออกแบบอย่างถูกต้องสามารถนำไปสู่การเพิ่มประสิทธิภาพอย่างมาก ตัวอย่างเช่นนิพจน์ที่ไม่สามารถระบุได้บนการเข้าร่วมเช่นการรวมกันของคุณสามารถห่อในคำสั่งใช้ประเมินเป็นชุดแล้วเข้าร่วมกับแบบสอบถามถัดไปโดยไม่ให้กลายเป็น RBAR ทดลองเล็กน้อย การสมัครข้ามเป็นเรื่องยากที่จะเชี่ยวชาญ แต่ก็คุ้มค่า!
SheldonH

0

ความแตกต่างของค่าเหล่านี้คืออะไรโปรด?

arithabort              1
ansi_null_dflt_on       1
ansi_defaults           0
ansi_warnings           1
ansi_padding            1
ansi_nulls              1

สิ่งเหล่านี้ (โดยเฉพาะอย่างยิ่ง arithabort) แสดงให้เห็นว่ามีผลกระทบต่อประสิทธิภาพการค้นหาอย่างจริงจังในลักษณะนี้


นี่เป็นเพราะมันเป็นกุญแจแคชแผนมากกว่าสิ่งใด ๆ เกี่ยวกับarithabortตัวเอง แต่มันไม่ได้? ตั้งแต่ SQL Server 2005 ฉันคิดว่าการตั้งค่านี้ไม่มีผลตราบเท่าที่ansi_warningsเปิดอยู่ (ในปี 2000 การดูที่มีการจัดทำดัชนีจะไม่ถูกใช้หากตั้งค่าไม่ถูกต้อง)
Martin Smith

@ มาร์ติน: ฉันไม่มีประสบการณ์โดยตรงเกี่ยวกับเรื่องนี้ แต่จำสิ่งที่อ่านเมื่อเร็ว ๆ นี้ และค้นหาคำตอบบางอย่างของมัน มันอาจช่วย OP ได้ แต่อาจไม่ ... แก้ไข: sqlblog.com/blogs/kalen_delaney/archive/2008/06/19/… ถอนหายใจ
gbn

ฉันได้อ่านคำกล่าวอ้างที่คล้ายกันนี้แล้ว ฉันไม่เคยเห็นสิ่งใดที่จะทำให้ฉันสามารถทำซ้ำได้ด้วยตัวเองหรือคำอธิบายเชิงตรรกะว่าทำไมการarithabortตั้งค่าควรมีอิทธิพลอย่างมากต่อประสิทธิภาพการทำงาน
Martin Smith

ARITHABORT, ANSI_WARNINGS, ANSI_PADDING และ ANSI_NULL คือ 1 ส่วนที่เหลือเป็น NULL
จอนแห่งการค้าทั้งหมด

FYI ฉันทำงานทั้งหมดใน SSMS ดังนั้นการตั้งค่าที่แตกต่างกันใน VS หรือลูกค้ารายอื่นไม่เป็นปัญหา
จอนแห่งการค้าทั้งหมด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.