어떤 세션이 어떤 임시 테이블을 보유하고 있는지 확인


14

임시 데이터베이스가 가득 찬 SQL Server 2005 데이터베이스가 있습니다. SQL Server Management Studio로 들어가서 tempdb의 모든 임시 테이블을 볼 수 있습니다. 어떤 세션이 어떤 임시 테이블을 보유하고 있는지 알 수 있습니까? 각 세션에서 사용되는 임시 테이블을 나열하는 쿼리가 이상적입니다.

감사,


1
임시 데이터베이스에서 공간을 사용하는 특정 사용자를 추적하고 싶습니다. 현재 관심있는 tempdb의 소비량입니다.
SQLMIKE

답변:


16

2007 년 Connect에 구축 할 것을 요청했습니다. 이 기능은 2008 년 릴리스에서 거부되었으며 몇 년 전에 Connect가 종료 될 때까지 무시되었습니다. SQL Server대한 새로운 피드백 사이트 에서 찾으려고 했지만 그 검색은 절대 쓰레기 수거통입니다. 내 요청의 제목은 "임시 테이블을 session_id에 매핑하는 dmv"입니다. 검색은 OR 만 수행 할 수 있기 때문에 "맵 임시 테이블"은 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)

이 Jonathan 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)

여기서 문제는 쿼리 텍스트로 테이블 이름을 상관시키려는 것입니다. 대부분의 경우 사용자는 여전히 테이블에 대해 쿼리를 실행 하지 않으므로 테이블을 만들거나 채운 테이블을 실행하지 않아도됩니다.

그러나 이것은 다른 독자 (또는 업그레이드 할 때)를위한 것이며 , #temp 테이블이 힙인 경우 2012+의 기본 추적은 더 이상 임시 테이블 개체 생성을 추적하지 않습니다 . 이것이 우연의 일치인지 또는 2012 년부터 모든 임시 테이블이 이제 음수object_id 라는 사실과 직접 관련이 있는지 확실하지 않습니다 . 물론 확장 된 이벤트로 이동하여이 정보를 수집하고 추적하는 데 도움이 될 수 있지만 많은 수동 작업이 될 수 있습니다. 더 이상 추적에서 추적되지 않는 것으로 확인했습니다. 선택하지 못할 수도 있습니다. 확장 이벤트 중 하나). 기본 추적 PK 또는 다른 제약 조건으로 생성되거나 생성 이벤트 후에 추가 된 제약 조건 또는 인덱스를 사용하여 생성 된 #temp 테이블을 선택하지만 위의 시간 기반 제한을 완화해야합니다. 창조).

이 사이트에서 유용한 다른 답변들 :

또한 SQL Server 2012 이상에서이 정보를 추적하기위한 사용자 지정 확장 이벤트 세션을 통해 이에 대한 블로그를 작성했습니다.

그리고 폴 화이트 (Paul White)는 페이지를 직접 읽는 것에 대해 블로그를 작성했습니다.


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;

이 쿼리는 할당 / 할당 된 페이지, 작업의 SQL 텍스트 (사용 가능한 경우) 등과 같은 상위 10 개 작업에 대한 유용한 정보를 가져옵니다.

이 DMV는 훌륭한 정보로 가득 차 있으므로 더 많은 데이터가 필요한 경우 당기는 내용과 혼합하여 일치시킬 수 있습니다. 그러나 이것은 현재 tempdb 소비 작업 문제를 해결하기위한 시작점이어야합니다.


고마워요 이상한 점은 tempdb에서 '상위 테이블 별 디스크 사용량'보고서를 실행하면 가장 많은 공간을 사용하는 테이블이 st.text에 나타나지 않는 것입니다. 쿼리를 실행 한 후에도 테이블이 여전히 있습니다.
SQLMIKE

1
@SQLMIKE 가장 큰 테이블을 알고 싶다면에서 얻을 수 있습니다 tempdb.sys.dm_db_partition_stats. 불행히도 어떤 사본이 #some_table_name어떤 사용자에게 속 하는지 알 수 없으며 주어진 시간에 해당 테이블을 참조하는 명령문 텍스트를 항상 가져올 수 없습니다. 사용자가 현재 실행중인 쿼리가 아닐 수도 있습니다. 당신은 참조 할 수 있습니다
아론 버트 랜드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.