SQL*_*IKE 17 sql-server-2005 sql-server tempdb
我们有一个 SQL Server 2005 数据库,临时数据库已满。通过进入 SQL Server Management Studio,我可以看到 tempdb 中的所有临时表。是否可以判断哪个会话持有哪个临时表?理想情况下,一个查询将列出每个会话使用的临时表。
谢谢,
Aar*_*and 19
早在 2007 年,我就要求在 Connect 上内置一些东西。这在 2008 年版本中被拒绝,随后被忽略,直到几年前 Connect 死了。我试图在 SQL Server 的新反馈站点上找到它](该站点也已被终止,但该搜索绝对是垃圾站火。我的请求的标题是“将临时表映射到 session_id 的 dmv”-因为搜索可以only do OR,"map temp table" 返回 118 页的结果。谷歌似乎暗示该项目在他们杀死 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)
Run Code Online (Sandbox Code Playgroud)
无耻地从这篇 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)
Run Code Online (Sandbox Code Playgroud)
这里的问题是试图通过查询文本关联表名;这只是不切实际,因为在大多数情况下,用户并不仍在对该表执行查询(更不用说仍在运行创建/填充它的表)。
但是,这是针对其他读者(或升级时的您),如果 #temp 表是堆,则2012+ 中的默认跟踪不再跟踪临时表对象创建。不确定这是巧合还是与以下事实直接相关:从 2012 年开始,所有临时表现object_id在都有一个否定的. 您当然可以使用 Extended Events 来帮助您收集和跟踪此信息,但这可能需要大量手动工作(并且我仅确认不再跟踪此信息 - 您可能无法选择它在扩展事件中或者)。默认跟踪将 选择使用 PK 或其他约束创建的 #temp 表,或者在创建事件之后添加的约束或索引,但是您必须放松上述基于时间的限制(索引可以在 100 毫秒之后创建)创建)。
本网站上的其他一些可能有用的答案:
我还写了一篇关于此的博客,使用自定义扩展事件会话来跟踪 SQL Server 2012 及更高版本中的此信息:
保罗怀特写了关于直接阅读页面的博客(不完全适合胆小的人,也不容易以任何方式自动化):
这是一个查询,应该可以让您开始查找您正在寻找的信息:
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;
Run Code Online (Sandbox Code Playgroud)
此查询提取前 10 个任务的有用信息,例如分配/解除分配的页面、任务的 SQL 文本(如果可用)等。
这些 DMV 充满了重要信息,因此如果您需要更多数据,那么您可以混合搭配您正在提取的数据。但这应该是对当前 tempdb 消耗任务进行故障排除的起点。