ค้นหาเซสชันที่กำลังถือตารางชั่วคราว


14

เรามีฐานข้อมูล SQL Server 2005 ฐานข้อมูลชั่วคราวเต็ม โดยไปที่ Studio จัดการเซิร์ฟเวอร์ SQL ฉันสามารถดูตารางชั่วคราวทั้งหมดใน tempdb เป็นไปได้หรือไม่ที่จะบอกได้ว่าเซสชันใดกำลังถือตารางอุณหภูมิใดอยู่ เป็นการดีที่แบบสอบถามซึ่งจะแสดงรายการตารางอุณหภูมิที่ใช้โดยแต่ละเซสชั่น

ขอบคุณ


1
เราต้องการติดตามผู้ใช้เฉพาะที่ใช้พื้นที่ในฐานข้อมูล temp เป็นการใช้งาน 'tempdb' ที่เราสนใจในปัจจุบัน
SQLMIKE

คำตอบ:


16

ฉันถามหาบางอย่างที่จะสร้างขึ้นในปี 2007 บน Connect สิ่งนี้ถูกปฏิเสธสำหรับการเปิดตัวในปี 2008 และไม่สนใจในภายหลังจนกระทั่ง Connect เสียชีวิตเมื่อไม่กี่ปีที่ผ่านมา ฉันพยายามค้นหามันบนไซต์ผลตอบรับใหม่สำหรับ SQL Serverแต่การค้นหานั้นเป็นการดับเพลิงอย่างสมบูรณ์ ชื่อคำขอของฉันคือ "dmv to map temp table to session_id" - เนื่องจากการค้นหาทำได้เพียง OR หรือ "map temp table" ส่งคืนผลลัพธ์ 118 หน้า Google ดูเหมือนว่าจะแนะนำรายการที่ไม่ได้ทำการตัดเมื่อพวกเขาถูกฆ่าตาย Connect

ในระหว่างนี้สำหรับ SQL Server 2005 และ 2008 คุณควรสามารถดึงข้อมูลนี้จากการติดตามเริ่มต้น:

DECLARE @FileName VARCHAR(MAX)  

SELECT @FileName = SUBSTRING(path, 0,
   LEN(path)-CHARINDEX('\', REVERSE(path))+1) + '\Log.trc'  
FROM sys.traces   
WHERE is_default = 1;  

SELECT   
     o.name,   
     o.OBJECT_ID,  
     o.create_date, 
     gt.NTUserName,  
     gt.HostName,  
     gt.SPID,  
     gt.DatabaseName,  
     gt.TEXTData 
FROM sys.fn_trace_gettable( @FileName, DEFAULT ) AS gt  
JOIN tempdb.sys.objects AS o   
     ON gt.ObjectID = o.OBJECT_ID  
WHERE gt.DatabaseID = 2 
  AND gt.EventClass = 46 -- (Object:Created Event from sys.trace_events)  
  AND o.create_date >= DATEADD(ms, -100, gt.StartTime)   
  AND o.create_date <= DATEADD(ms, 100, gt.StartTime)

ยกลงคอจากการโพสต์บล็อกนี้โจนาธาน Kehayias

ในการกำหนดการใช้พื้นที่คุณสามารถปรับปรุงสิ่งนี้เพื่อเข้าร่วมในข้อมูลจากมุมมองเช่นsys.db_db_partition_stats-:

DECLARE @FileName VARCHAR(MAX)  

SELECT @FileName = SUBSTRING(path, 0,
   LEN(path)-CHARINDEX('\', REVERSE(path))+1) + '\Log.trc'  
FROM sys.traces   
WHERE is_default = 1;  

SELECT   
     o.name,   
     o.OBJECT_ID,  
     o.create_date, 
     gt.NTUserName,  
     gt.HostName,  
     gt.SPID,  
     gt.DatabaseName,  
     gt.TEXTData,
     row_count = x.rc,
     used_page_count = x.upc
FROM sys.fn_trace_gettable( @FileName, DEFAULT ) AS gt  
JOIN tempdb.sys.objects AS o   
     ON gt.ObjectID = o.OBJECT_ID
INNER JOIN
(
 SELECT [object_id], SUM(row_count), SUM(used_page_count)
   FROM tempdb.sys.dm_db_partition_stats
   WHERE index_id IN (0,1)
   GROUP BY [object_id]
) AS x(id, rc, upc)
ON x.id = o.[object_id]
WHERE gt.DatabaseID = 2 
  AND gt.EventClass = 46 -- (Object:Created Event from sys.trace_events)  
  AND o.create_date >= DATEADD(ms, -100, gt.StartTime)   
  AND o.create_date <= DATEADD(ms, 100, gt.StartTime)

ปัญหาที่นี่พยายามเชื่อมโยงชื่อตารางด้วยข้อความแบบสอบถาม สิ่งนี้ไม่สามารถใช้งานได้จริงเนื่องจากผู้ใช้ส่วนใหญ่ยังไม่ได้เรียกใช้คิวรีกับตารางนั้น

อย่างไรก็ตามและนี่สำหรับผู้อ่านอื่น ๆ (หรือสำหรับคุณเมื่อคุณอัพเกรด) การติดตามเริ่มต้นในปี 2012+ จะไม่ติดตามการสร้างวัตถุตารางชั่วคราวอีกต่อไปหากตาราง #temp เป็นฮีป ไม่แน่ใจว่าเป็นเรื่องบังเอิญหรือโดยตรงที่เกี่ยวข้องกับความจริงที่ว่าเริ่มต้นในปี 2012 ทุกตารางชั่วคราวขณะนี้มีการลบ object_idแน่นอนคุณสามารถย้ายไปยังกิจกรรมเพิ่มเติมเพื่อช่วยคุณรวบรวมและติดตามข้อมูลนี้ แต่นั่นอาจเป็นงานที่ต้องทำด้วยมือจำนวนมาก (และฉันยืนยันว่านี่ไม่ได้ติดตามในการติดตามอีกต่อไป - คุณอาจไม่สามารถเลือกได้ ในเหตุการณ์ที่ขยายเพิ่มเติมอย่างใดอย่างหนึ่ง) การติดตามเริ่มต้นจะ หยิบ #temp ตารางที่สร้างด้วย PK หรือข้อ จำกัด อื่น ๆ หรือเพิ่มข้อ จำกัด หรือดัชนีหลังจากเหตุการณ์การสร้าง แต่คุณจะต้องคลายข้อ จำกัด ตามเวลาด้านบน (ดัชนีสามารถสร้างได้ช้ากว่า 100 มิลลิวินาทีหลังจากนั้น การสร้าง)

คำตอบอื่น ๆ ในเว็บไซต์นี้ที่อาจมีประโยชน์:

ฉันยัง blogged เกี่ยวกับเรื่องนี้ด้วยการขยายกิจกรรมที่กำหนดเองเพื่อติดตามข้อมูลนี้ใน SQL Server 2012 และสูงกว่า:

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


5

ต่อไปนี้เป็นคำถามที่คุณควรเริ่มต้นจากการค้นหาข้อมูลที่คุณกำลังมองหา:

select top 10
    tsu.session_id,
    tsu.request_id,
    r.command,
    s.login_name,
    s.host_name,
    s.program_name,
    total_objects_alloc_page_count = 
        tsu.user_objects_alloc_page_count + tsu.internal_objects_alloc_page_count,
    tsu.user_objects_alloc_page_count,
    tsu.user_objects_dealloc_page_count,
    tsu.internal_objects_alloc_page_count,
    tsu.internal_objects_dealloc_page_count,
    st.text
from sys.dm_db_task_space_usage tsu
inner join sys.dm_exec_requests r
on tsu.session_id = r.session_id
and tsu.request_id = r.request_id
inner join sys.dm_exec_sessions s
on r.session_id = s.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
where tsu.user_objects_alloc_page_count > 0
or tsu.internal_objects_alloc_page_count > 0
order by total_objects_alloc_page_count desc;

แบบสอบถามนี้ดึงข้อมูลที่เป็นประโยชน์สำหรับงาน 10 อันดับแรกเช่นหน้าที่จัดสรร / ยกเลิกการจัดสรรข้อความ SQL ของงาน (หากมี) เป็นต้น

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


ขอบคุณที่ดูดีมาก สิ่งที่แปลกคือถ้าฉันเรียกใช้รายงาน 'การใช้งานดิสก์โดยตารางด้านบน' ใน tempdb ตารางที่ใช้พื้นที่ส่วนใหญ่จะไม่ปรากฏใน st.text ตารางยังคงอยู่ที่นั่นหลังจากฉันเรียกใช้แบบสอบถาม
SQLMIKE

1
@SQLMIKE ถ้าคุณเพียงต้องการที่จะทราบว่าตารางเป็นที่ใหญ่ที่สุด, tempdb.sys.dm_db_partition_statsคุณจะได้รับจาก น่าเสียดายที่คุณไม่สามารถบอกได้ว่าสำเนาใด#some_table_nameเป็นของผู้ใช้คนใดและคุณจะไม่สามารถดึงข้อความคำสั่งที่อ้างอิงตารางนั้น ณ เวลาใดก็ตามซึ่งอาจไม่ใช่แบบสอบถามที่ผู้ใช้กำลังทำงานอยู่ คุณอาจต้องการเห็นสิ่งนี้และสิ่งนี้
Aaron Bertrand
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.