ผู้ประกอบการใช้ tempdb ในการรั่วไหลของข้อมูลระหว่างการดำเนินการกับระดับที่หก


17

ฉันกำลังดิ้นรนเพื่อลดต้นทุนของการดำเนินการเรียงลำดับในแผนแบบสอบถามด้วยOperator usedtempdb คำเตือนto spill data during execution with spill level 2

ฉันพบโพสต์หลายรายการที่เกี่ยวข้องกับข้อมูลการรั่วไหลในระหว่างการดำเนินการกับการรั่วไหลระดับ 1แต่ไม่ใช่ระดับ 2 ดูเหมือนว่าระดับ 1 จะทำให้สถิติล้าสมัยแล้วระดับ 2 เป็นอย่างไร level 2ฉันไม่สามารถหาอะไรที่เกี่ยวข้องกับ

ฉันพบบทความนี้น่าสนใจมากที่เกี่ยวข้องกับคำเตือนการเรียง:

อย่าเพิกเฉยต่อคำเตือนการเรียงลำดับใน SQL Server

เซิร์ฟเวอร์ SQL ของฉัน

Microsoft SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64) 17 มิถุนายน 2016 19:14:09 ลิขสิทธิ์ (c) Microsoft Corporation รุ่นองค์กรองค์กร (64 บิต) บน Windows NT 6.3 (รุ่น 9600:) (Hypervisor)

ฮาร์ดแวร์ของฉัน

เรียกใช้คิวรีด้านล่างเพื่อค้นหาฮาร์แวร์:

- ข้อมูลฮาร์ดแวร์จาก SQL Server 2012

SELECT cpu_count AS [Logical CPU Count], hyperthread_ratio AS [Hyperthread Ratio],
cpu_count/hyperthread_ratio AS [Physical CPU Count], 
physical_memory_kb/1024 AS [Physical Memory (MB)], affinity_type_desc, 
virtual_machine_type_desc, sqlserver_start_time
FROM sys.dm_os_sys_info WITH (NOLOCK) OPTION (RECOMPILE);

ป้อนคำอธิบายรูปภาพที่นี่

หน่วยความจำที่จัดสรรในปัจจุบัน

SELECT
(physical_memory_in_use_kb/1024) AS Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024) AS Locked_pages_used_Sqlserver_MB,
(total_virtual_address_space_kb/1024) AS Total_VAS_in_MB,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory;

ป้อนคำอธิบายรูปภาพที่นี่

เมื่อฉันเรียกใช้แบบสอบถามด้วยขอบเขตหนึ่งปีฉันไม่ได้รับคำเตือนใด ๆ ตามภาพด้านล่าง:

ป้อนคำอธิบายรูปภาพที่นี่

แต่เมื่อฉันเรียกใช้เพียงขอบเขต 1 วันฉันจะได้รับคำเตือนนี้on the sort operator:

ป้อนคำอธิบายรูปภาพที่นี่

นี่คือแบบสอบถาม:

    DECLARE @FromDate SMALLDATETIME = '19-OCT-2016 11:00'
    DECLARE @ToDate   SMALLDATETIME = '20-OCT-2016 12:00'




    SELECT      DISTINCT
                a.strAccountCode ,
                a.strAddressLine6 ,
                a.strPostalCode ,
                CASE    WHEN a.strCountryCode IN ('91','92') THEN 'GB-Int'
                        ELSE a.strCountryCode
                        END AS [strCountryCode]
    FROM        Bocss2.dbo.tblBAccountParticipant AS ap
    INNER JOIN  Bocss2.dbo.tblBAccountParticipantAddress AS apa ON ap.lngParticipantID = apa.lngParticipantID
                                                                AND apa.sintAddressTypeID = 2
    INNER JOIN  Bocss2.dbo.tblBAccountHolder AS ah ON ap.lngParticipantID = ah.lngParticipantID
    INNER JOIN  Bocss2.dbo.tblBAddress AS a ON apa.lngAddressID = a.lngAddressID
                                            AND a.blnIsCurrent = 1
    INNER JOIN  Bocss2.dbo.tblBOrder AS o ON ap.lngParticipantID = o.lngAccountParticipantID
                                        AND o.sdtmOrdCreated >= @FromDate
                                        AND o.sdtmOrdCreated < @ToDate

OPTION(RECOMPILE)

แผนแบบสอบถามอยู่ที่นี่

แผนแบบสอบถามโดยใช้ pastetheplan

คำถาม: 1) ในแผนแบบสอบถามฉันเห็นสิ่งนี้:

StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="70" 

ทำไม 70 ฉันใช้เซิร์ฟเวอร์ sql 2014

2) ฉันจะกำจัดตัวดำเนินการเรียงลำดับนั้นได้อย่างไร (ถ้าทำได้)

3) ฉันเคยเห็นอายุการใช้งานของเพจค่อนข้างต่ำนอกจากการเพิ่มหน่วยความจำเพิ่มเติมไปยังเซิร์ฟเวอร์นี้แล้วมีสิ่งอื่นอีกไหมที่ฉันสามารถดูเพื่อดูว่าฉันสามารถป้องกันคำเตือนนี้ได้หรือไม่?

ไชโย

อัปเดตหลังจากคำตอบจาก Shanky และ Paul White

ฉันตรวจสอบสถิติของฉันตามสคริปต์ด้านล่างแล้วพวกเขาดูเหมือนถูกต้องและได้รับการปรับปรุง

นี่คือดัชนีและตารางทั้งหมดที่ใช้ในแบบสอบถามนี้

DBCC SHOW_STATISTICS ('dbo.tblBAddress','IDXF_tblBAddress_lngAddressID__INC')
GO
DBCC SHOW_STATISTICS  ('dbo.tblBOrder','IX_tblBOrder_sdtmOrdCreated_INCL')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountHolder','PK_tblAccountHolder')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipant','PK_tblBAccountParticipants')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipantAddress','IDXF_tblBAccountParticipantAddress_lngParticipantID')
GO

นี่คือสิ่งที่ฉันได้รับคืน:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

นี่เป็นผลลัพธ์บางส่วน แต่ฉันกลับมาเยี่ยมอีกครั้ง

สำหรับการอัปเดตสถิติฉันมีOla Hallengrenอยู่ในขณะนี้

งาน Optimize Index - กำหนดให้ทำงานสัปดาห์ละครั้ง - วันอาทิตย์

EXECUTE [dbo].[IndexOptimize] 
@Databases = 'USER_DATABASES,-%Archive', 
@Indexes = 'ALL_INDEXES' , 
@FragmentationLow = NULL,
@FragmentationMedium = NULL,
@FragmentationHigh = NULL,
@PageCountLevel=1000,
@StatisticsSample =100
,@UpdateStatistics = 'Index', 
@OnlyModifiedStatistics = 'Y',
@TimeLimit=10800, 
@LogToTable = 'Y'

แม้ว่าสถิติดูเหมือนจะได้รับการปรับปรุงหลังจากที่ฉันเรียกใช้สคริปต์ต่อไปนี้ฉันไม่ได้รับคำเตือนเพิ่มเติมเกี่ยวกับตัวดำเนินการเรียงลำดับ

UPDATE STATISTICS [Bocss2].[dbo].[tblBOrder]  WITH FULLSCAN
--1 hour  04 min 14 sec

UPDATE STATISTICS [Bocss2].[dbo].tblBAddress  WITH FULLSCAN
-- 45 min 29 sec

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountHolder WITH FULLSCAN
-- 26 SEC

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipant WITH FULLSCAN
-- 4 min

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipantAddress WITH FULLSCAN
-- 7 min 3 sec

เวลาสอบถามลดลงเท่าใด
มีอิทธิพล

ฉันไม่สามารถใช้โซลูชันที่จะทำให้ฉันปรับปรุงสถิติบนตารางขนาดใหญ่เช่นนี้ วิธีแก้ปัญหาคือการแบ่งพาร์ติชันตารางและใช้สถิติแบบเพิ่มหน่วย แต่ฉันไม่เคยลงมือปฏิบัติเพราะฉันออกจากนายจ้างคนนั้น สิ่งที่ฉันชอบที่จะนำมาใช้
Marcello Miorelli

คำตอบ:


17

แล้วระดับ 2 ล่ะ ฉันไม่พบสิ่งใดที่เกี่ยวข้องกับระดับ 2

ตามเอกสาร MS เก่านี้หมายเลขในการรั่วไหลของ Tempdb หมายถึงจำนวนการผ่านที่ต้องการผ่านข้อมูลเพื่อจัดเรียงข้อมูล ดังนั้น Spill 1 จึงต้องผ่าน 1 ครั้งเพื่อจัดเรียงข้อมูลและ 2 หมายความว่าต้องผ่าน 2 ครั้ง

การอ้างอิงจากบล็อก:

หากเคียวรีที่เกี่ยวข้องกับการดำเนินการเรียงลำดับสร้างคลาสเหตุการณ์เรียงคำเตือนที่มีค่าระดับการรั่วไหลของ 2 ประสิทธิภาพของแบบสอบถามอาจได้รับผลกระทบเนื่องจากต้องผ่านการส่งผ่านข้อมูลจำนวนมากเพื่อจัดเรียงข้อมูล ในตัวอย่างด้านล่างเราเห็นค่าระดับการรั่วไหลของ 1 ซึ่งหมายความว่าหนึ่งผ่านข้อมูลก็เพียงพอที่จะเรียงลำดับ

ทำไม 70 ฉันใช้เซิร์ฟเวอร์ sql 2014

เพราะนี่คือระดับความเข้ากันของฐานข้อมูลในภาพไม่ได้ 120 (ซึ่งหมายถึงระดับความเข้ากันได้ปี 2014 ฐานข้อมูล) ตั้งแต่ยังไม่ได้ 120 แบบสอบถามจะถูกประมวลผลโดยใช้เก่า cardinality ประมาณค่า (CE) CardinalityEstimationModelVersion="70"รุ่นที่จะเรียกว่าเป็น ฉันแน่ใจว่าคุณทราบว่าจาก SQL Server 2014 เรามี CE ใหม่

ฉันจะกำจัดตัวดำเนินการเรียงลำดับนั้นได้อย่างไร (ถ้าทำได้)

คำสั่งที่แตกต่างที่คุณใช้ทำให้การดำเนินการเรียง ข้อมูลที่ถูกจัดเรียงไม่พอดีกับหน่วยความจำดังนั้นข้อมูลจะถูกกระจายไปยัง tempdb และเมื่อเกิดเหตุการณ์นี้คำเตือนการเรียงลำดับที่มีเครื่องหมายอัศเจรีย์สีเหลืองจะได้รับในแผนการดำเนินการ คำเตือนการเรียงลำดับอาจไม่ใช่ปัญหาเสมอไป

คุณสามารถดูได้ในแผนการดำเนินการที่จำนวนแถวที่จะจัดเรียงโดยประมาณคือ 1 แต่พบ 16,353 ณ เวลารันไทม์ จำนวนหน่วยความจำที่สงวนไว้สำหรับการจัดเรียงจะขึ้นอยู่กับขนาด (โดยประมาณ) ของอินพุตที่คาดไว้และไม่สามารถขยายได้ระหว่างการดำเนินการ (ในกรณีนี้)

ทุนหน่วยความจำขนาดเล็กสำหรับการค้นหา (1632KB) ที่ใช้ร่วมกันนอกจากนี้ยังเห็นพ้องกันออกไปในหมู่ผู้ประกอบการรันหน่วยความจำมาก (เรียงลำดับและ'เพิ่มประสิทธิภาพ'วงร่วม) ในแผนของคุณนั่นหมายถึง 33.33% (544KB) พร้อมให้จัดเรียงขณะที่อ่านแถว (ส่วนของหน่วยความจำอินพุต) นี่คือหน่วยความจำไม่พอที่จะจัดเรียง 16,353 แถวจึงรั่วไหลไปtempdb การรั่วไหลของระดับเดียวนั้นไม่เพียงพอที่จะทำให้การเรียงลำดับเสร็จสมบูรณ์ดังนั้นจึงจำเป็นต้องมีการหกระดับ (ดูการอ้างอิงที่ส่วนท้ายเพื่อดูรายละเอียดเพิ่มเติมเกี่ยวกับระดับการหก)

เรียงลำดับคุณสมบัติ

เรียงลำดับคุณสมบัติตามที่ดูใน SQL Sentry Plan Explorer

การอัปเดตสถิติน่าจะช่วยในเรื่องการประมาณค่า cardinality tblBOrderคุณอาจจะพบปัญหาที่สำคัญจากน้อยไปมากโดยเฉพาะอย่างยิ่งบนโต๊ะ การเลือกอย่างง่ายจากตารางนั้นด้วยวันที่ตามตัวอักษรจากคำถามของคุณน่าจะประมาณหนึ่งแถวในขณะนี้

ฉันเคยเห็นอายุการใช้งานของเพจค่อนข้างต่ำนอกจากการเพิ่มหน่วยความจำเพิ่มเติมลงในเซิร์ฟเวอร์นี้แล้วยังมีสิ่งอื่นอีกไหมที่ฉันสามารถดูเพื่อดูว่าฉันสามารถป้องกันคำเตือนนี้ได้หรือไม่

PLE เป็นตัวบ่งชี้ปริมาณของกิจกรรม I / O เพิ่มขึ้นหรือไม่? สิ่งนี้จะเกิดขึ้นบ่อยครั้งหรือเฉพาะเมื่อคุณเรียกใช้แบบสอบถามหรือมีสิ่งนี้เกิดขึ้นเพียงวันนี้ หลีกเลี่ยงปฏิกิริยาสะบัดหัวเข่าก่อนอื่นเราต้องให้แน่ใจว่าคุณกำลังเผชิญกับแรงกดดันของหน่วยความจำจริงหรือมีคิวรี่อันธพาลบางอันที่สร้าง I / O มากเกินไปทำให้เกิดสิ่งนี้ อย่างไรก็ตามคุณมีหน่วยความจำ 97 G ที่กำหนดให้กับ SQL Server แล้ว

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับระดับการรั่วไหลและปัญหาหลักจากน้อยไปมากดูที่:

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