วางแผนขนาดแคชและหน่วยความจำที่สงวนไว้


18

เมื่อรันเคียวรีรวมถึงแผนการดำเนินการตามจริงผู้ดำเนินการรูท ( SELECT) จะบอกฉันว่าขนาดแผนแคชคือ 32KB

แบบสอบถามที่เข้าร่วมsys.dm_exec_cached_plansและsys.dm_os_memory_objectsมองไปที่แผนดังกล่าวกล่าวว่าค่าสำหรับpages_in_bytesและmax_pages_in_bytesคือ 32768 (32KB) ซึ่งตรงกับขนาดแผนแคช

สิ่งที่ฉันไม่เข้าใจคือสิ่งที่มีค่าsys.dm_exec_cached_plans.size_in_bytesซึ่งคือ 49152 (48KB) ฉันได้อ่าน BOL ในคอลัมน์เหล่านี้ทั้งหมดและโดยเฉพาะsize_in_bytesที่บอกว่า:

" จำนวนไบต์ที่ใช้โดยวัตถุแคช "

ฉันไม่สามารถรับจิ๊กซอว์ชิ้นสุดท้ายได้เพื่อทำความเข้าใจความหมายของมัน

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

ดังนั้นคำถามของฉันคือ:

  • อะไรsize_in_bytesจริงๆหมายถึง
  • เพราะเหตุใดจึงมีมูลค่าสูงกว่า "ขนาดแผนแคช"
  • จำนวนหน่วยความจำคงที่สำหรับตัวดำเนินการทั้งหมด / ตัวจองที่จองไว้กับ "ขนาดแผนแคช" (32Kb ในตัวอย่างของฉัน) หรือที่อื่น?

ฉันรู้ว่าพวกเขาเป็น DMV ที่แตกต่างกันและมีฟังก์ชั่นต่างกัน แผนเรียบเรียง (แคช) sys.dm_exec_cached_plansรวมsys.dm_os_memory_objectsในmemory_object_addressคอลัมน์ เหตุผลที่ฉันโพสต์คำถามที่นี่คือฉันขอความช่วยเหลือในเรื่องนี้เข้าใจวิธีตีความ DMV และคอลัมน์ของพวกเขา

ถ้าsize_in_bytesขนาดของแผนแคชทำไม SQL Server ถึงพูดถึงค่าอื่นในแผนการดำเนินการจริง

แบบสอบถามใหม่หมายเลขใหม่:

  • แผนจริง
    • ขนาดแผนแคช 16KB
    • CompileMemory 96KB
  • DMVs:
    • sys.dm_exec_cached_plans.size_in_bytes 24KB
    • sys.dm_os_memory_objects.pages_in_bytes, .max_pages_in_bytes 16KB

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

Microsoft SQL Server 2012 - 11.0.5343.0 (X64)

คำตอบ:


12

สาเหตุที่size_in_bytesเขตข้อมูลของsys.dm_exec_cached_plansDMV อย่างน้อยก็ในแง่ของ "แผนการรวบรวม" มีขนาดใหญ่กว่าCachedPlanSizeแอตทริบิวต์ของQueryPlanโหนดในแผน XML เนื่องจากแผนการรวบรวมไม่เหมือนกับแผนแบบสอบถาม แผนคอมไพล์ประกอบด้วยหน่วยความจำหลายออบเจ็กต์ขนาดรวมซึ่งเท่ากับsize_in_bytesฟิลด์ ดังนั้นคำอธิบายของ " จำนวนไบต์ที่ใช้โดยวัตถุแคช " ที่คุณพบในเอกสารมีความถูกต้อง เป็นเพียงการตีความผิดที่ "วัตถุแคช" หมายถึงชื่อ DMV ได้ง่ายและคำว่า "แผน" มีความหมายหลายอย่าง

Compiled Plan เป็นคอนเทนเนอร์ที่เก็บข้อมูลหลากหลายที่เกี่ยวข้องกับแบทช์แบบสอบถาม(เช่นไม่ใช่คำสั่งเดียว) หนึ่ง (หรือมากกว่า) ของชิ้นส่วนเหล่านั้นเป็นแผนเคียวรี แผนการที่คอมไพล์มีหน่วยความจำระดับสูงสุดวัตถุวัตถุของMEMOBJ_COMPILE_ADHOCซึ่งเป็นแถวในsys.dm_os_memory_objectsที่ถูกเชื่อมโยงผ่านmemory_object_addressเขตข้อมูลใน DMV ทั้งสอง หน่วยความจำวัตถุนี้มีตารางสัญลักษณ์การรวบรวมพารามิเตอร์เชื่อมโยงไปยังวัตถุที่เกี่ยวข้องแคช accessor แคชเมตาดาต้า TDS และอาจเป็นไปได้บางรายการอื่น ๆ แผนการคอมไพล์ถูกแชร์ระหว่างเซสชัน / ผู้ใช้ที่ดำเนินการแบทช์เดียวกันด้วยการตั้งค่าเซสชันเดียวกัน อย่างไรก็ตามวัตถุที่เกี่ยวข้องบางอย่างไม่ถูกแชร์ระหว่างเซสชัน / ผู้ใช้

แผนการคอมไพล์ยังมีวัตถุที่ต้องพึ่งพาอย่างน้อยหนึ่งรายการที่สามารถพบได้โดยการส่งผ่านplan_handle( sys.dm_exec_cached_plansเข้า) เข้าสู่sys.dm_exec_cached_plan_dependent_objectsDMF มีวัตถุที่ต้องพึ่งพาสองชนิด: แผนปฏิบัติการ (หน่วยความจำวัตถุ = MEMOBJ_EXECUTE ) และเคอร์เซอร์ (วัตถุหน่วยความจำ = MEMOBJ_CURSOREXEC ) จะมีวัตถุเคอร์เซอร์ 0 ตัวหรือมากกว่าหนึ่งตัวต่อเคอร์เซอร์ จะมีวัตถุแผนปฏิบัติการหนึ่งรายการขึ้นไปหนึ่งวัตถุสำหรับแต่ละผู้ใช้ที่ดำเนินการแบทช์เดียวกันดังนั้นแผนปฏิบัติการไม่ได้แบ่งปันระหว่างผู้ใช้ แผนปฏิบัติการมีพารามิเตอร์รันไทม์และข้อมูลตัวแปรโลคัลสถานะรันไทม์เช่นคำสั่งที่ดำเนินการในปัจจุบันรหัสวัตถุสำหรับวัตถุที่สร้างขึ้นในเวลาทำงาน (ฉันถือว่านี่หมายถึงตัวแปรตารางตารางชั่วคราวขั้นตอนการจัดเก็บชั่วคราว ฯลฯ ) และรายการอื่น ๆ ที่เป็นไปได้

แต่ละคำสั่งภายในชุดคำสั่งหลายชุดจะมีอยู่ในคำชี้แจงที่รวบรวม (หน่วยความจำวัตถุ = MEMOBJ_STATEMENT ) ขนาดของแต่ละคำสั่งที่คอมไพล์ (เช่นpages_in_bytes) หารด้วย 1024 ควรตรงกับCachedPlanSize="xx"ค่าของ<QueryPlan>โหนดในแผน XML คำสั่งที่คอมไพล์มักจะมีหนึ่ง (อาจมากกว่า?) เชื่อมโยงแบบสอบถามแบบสอบถามรันไทม์ (หน่วยความจำวัตถุ = MEMOBJ_XSTMT ) สุดท้ายสำหรับแต่ละแผนแบบสอบถามรันไทม์ที่เป็นแบบสอบถามควรมีบริบทการดำเนินการแบบสอบถามที่เกี่ยวข้อง (หน่วยความจำวัตถุ = MEMOBJ_QUERYEXECCNTXTFORSE )

สำหรับคำสั่งที่คอมไพล์แบทช์คำสั่งเดี่ยวไม่มีคำสั่งที่คอมไพล์แยกต่างหาก (เช่นMEMOBJ_STATEMENT ) หรือแผนคิวรีรันไทม์แยกต่างหาก (เช่นMEMOBJ_XSTMT ) ค่าสำหรับแต่ละวัตถุเหล่านั้นจะถูกเก็บไว้ในวัตถุแผนหลักที่รวบรวม (เช่นMEMOBJ_COMPILE_ADHOC ) และในกรณีนั้นpages_in_bytesค่าสำหรับวัตถุหลักนั้นหารด้วย 1024 ควรตรงกับCachedPlanSizeขนาดใน<QueryPlan>โหนดของแผน XML ค่าเหล่านั้นจะไม่ถือเอาเป็นอย่างไรก็ตามในแบทช์หลายคำสั่ง


size_in_bytesคุ้มค่าที่จะได้รับจากข้อสรุปรายการในsys.dm_os_memory_objectsDMV (รายการที่ระบุไว้ข้างต้นเป็นตัวหนา) ทั้งหมดที่เกี่ยวข้องกับdm_os_memory_objects.page_allocator_addressการที่แผนรวบรวม เคล็ดลับในการรับค่าที่ถูกต้องคือการขอรับmemory_object_addressจากsys.dm_exec_cached_plansสำหรับแผนคอมไพล์เฉพาะก่อนจากนั้นใช้เพื่อรับแถวMEMOBJ_COMPILE_ADHOC ที่สอดคล้องกันจากsys.dm_os_memory_objectsตามmemory_object_addressฟิลด์ จากนั้นจับpage_allocator_addressค่าจากsys.dm_os_memory_objectsแถวนั้นและใช้เพื่อจับแถวทั้งหมดจากsys.dm_os_memory_objectsที่มีpage_allocator_addressค่าเท่ากัน (โปรดทราบว่าเทคนิคนี้ใช้ไม่ได้กับวัตถุประเภทแคชอื่น: Parse Tree , Extended Proc , CLR Compiled ProcและCLR Compiled Func.)

ใช้memory_object_addressค่าที่ได้รับจากsys.dm_exec_cached_plansคุณสามารถดูส่วนประกอบทั้งหมดของแผนรวบรวมผ่านแบบสอบถามต่อไปนี้:

DECLARE @CompiledPlanAddress VARBINARY(8) = 0x00000001DC4A4060;

SELECT obj.memory_object_address, obj.pages_in_bytes, obj.type
FROM   sys.dm_os_memory_objects obj
WHERE  obj.page_allocator_address = (
                               SELECT planobj.page_allocator_address
                               FROM   sys.dm_os_memory_objects planobj
                               WHERE  planobj.memory_object_address = @CompiledPlanAddress
                              )
ORDER BY obj.[type], obj.pages_in_bytes;

แบบสอบถามด้านล่างนี้แสดงรายการแผนรวบรวมทั้งหมดsys.dm_exec_cached_plansพร้อมกับแผนแบบสอบถามและคำสั่งสำหรับแต่ละชุด แบบสอบถามโดยตรงด้านบนจะรวมอยู่ในแบบสอบถามด้านล่างผ่าน XML เป็นMemoryObjectsฟิลด์:

SELECT cplan.bucketid,
       cplan.pool_id,
       cplan.refcounts,
       cplan.usecounts,
       cplan.size_in_bytes,
       cplan.memory_object_address,
       cplan.cacheobjtype,
       cplan.objtype,
       cplan.plan_handle,
       '---' AS [---],
       qrypln.[query_plan],
       sqltxt.[text],
       '---' AS [---],
       planobj.pages_in_bytes,
       planobj.pages_in_bytes / 1024 AS [BaseSingleStatementPlanKB],
       '===' AS [===],
       cplan.size_in_bytes AS [TotalPlanBytes],
       bytes.AllocatedBytes,
       (SELECT CONVERT(VARCHAR(30), obj.memory_object_address, 1)
               AS [memory_object_address], obj.pages_in_bytes, obj.[type]
               --,obj.page_size_in_bytes
        FROM   sys.dm_os_memory_objects obj
        WHERE  obj.page_allocator_address = planobj.page_allocator_address
        FOR XML RAW(N'object'), ROOT(N'memory_objects'), TYPE) AS [MemoryObjects]
FROM   sys.dm_exec_cached_plans cplan
OUTER APPLY sys.dm_exec_sql_text(cplan.[plan_handle]) sqltxt
OUTER APPLY sys.dm_exec_query_plan(cplan.[plan_handle]) qrypln
INNER JOIN sys.dm_os_memory_objects planobj
        ON planobj.memory_object_address = cplan.memory_object_address
OUTER APPLY (SELECT SUM(domo.[pages_in_bytes]) AS [AllocatedBytes]
             FROM   sys.dm_os_memory_objects domo
             WHERE  domo.page_allocator_address = planobj.page_allocator_address) bytes
WHERE  cplan.parent_plan_handle IS NULL
AND    cplan.cacheobjtype IN (N'Compiled Plan', N'Compiled Plan Stub')
--AND cplan.plan_handle = 0x06000D0031CD572910529CE001000000xxxxxxxx
ORDER BY cplan.objtype, cplan.plan_handle;

โปรดทราบว่า:

  • TotalPlanBytesฟิลด์เป็นเพียงอีกคำสั่งของsys.dm_exec_cached_plans.size_in_bytesสนาม
  • AllocatedBytesฟิลด์คือผลรวมของวัตถุหน่วยความจำที่เกี่ยวข้องที่มักจะตรงกับTotalPlanBytes(คือsize_in_bytes)
  • AllocatedBytesฟิลด์เป็นครั้งคราวจะสูงกว่าTotalPlanBytes(คือsize_in_bytes) เนื่องจากการใช้หน่วยความจำที่เพิ่มขึ้นระหว่างการดำเนินการ สิ่งนี้ดูเหมือนจะเกิดขึ้นส่วนใหญ่เนื่องจากการคอมไพล์ซ้ำ (ซึ่งควรเห็นได้ชัดกับการusecountsแสดงฟิลด์1)
  • BaseSingleStatementPlanKBฟิลด์ควรตรงกับCachedPlanSizeแอตทริบิวต์ของQueryPlanโหนดใน XML แต่เฉพาะเมื่อใช้ชุดคำเดียว
  • สำหรับชุดงานที่มีหลายแบบสอบถามควรมีการทำเครื่องหมายเป็นแถวMEMOBJ_STATEMENTในsys.dm_os_memory_objectsหนึ่งแบบสอบถามสำหรับแต่ละแบบสอบถาม pages_in_bytesสนามแถวเหล่านี้ควรจะตรงกับแต่ละ<QueryPlan>โหนดของแผนการของ XML

แหล่งข้อมูล:

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