一時データベースがいっぱいになったSQL Server 2005データベースがあります。 SQL Server Management Studioに移動すると、tempdbのすべての一時テーブルを確認できます。どのセッションがどの一時テーブルを保持しているかを知ることはできますか?理想的には、各セッションで使用される一時テーブルをリストするクエリです。
おかげで、
私は、2007年にConnectに何かを組み込むことを求めました。これは2008年のリリースでは拒否され、その後数年前にコネクトが亡くなるまで無視されました。 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)
ここでの問題は、クエリテキストでテーブル名を関連付けることです。ほとんどの場合、ユーザーはそのテーブルに対してクエリを still 実行していないので、これは実用的ではありません(作成/設定したクエリをまだ実行していても構いません)。
ただし、これは他のリーダー(またはアップグレード時の読者)向けです2012+のデフォルトトレースは、一時テーブルオブジェクトの作成を追跡しません。 #tempテーブルはヒープです。それが偶然なのか、2012年以降のすべての一時テーブル すべての一時テーブルに負のobject_id
があるという事実に直接関連しているかは不明です。もちろん、この情報を収集および追跡するために拡張イベントに移動することもできますが、これはおそらく多くの手動作業です(そして、これがトレースで追跡されなくなったことを確認しました-選択できない場合があります拡張イベントでアップ)。デフォルトのトレース will は、PKまたはその他の制約で作成された、または作成イベントの後に追加された制約またはインデックスで作成された#tempテーブルを取得しますが、時間を緩める必要があります上記の制限に基づく制限(インデックスは、作成後100ミリ秒よりはるかに遅く作成できます)。
このサイトで役立つその他の回答:
SQL Server 2012以降でこの情報を追跡するためのカスタム拡張イベントセッションを使用して、これについてもブログを書いています。
また、Paul Whiteは、ページを直接読むことについてブログを書いています(気弱な人のためではなく、自動化も簡単ではありません)。
以下は、探している情報を見つけるためのクエリです。
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消費タスクのトラブルシューティングの開始点になるはずです。