Я попросил что-то встроить еще в 2007 году на Connect. Это было отклонено для выпуска 2008 года и впоследствии игнорировалось, пока Connect не умер несколько лет назад. Я пытался найти его на новом сайте обратной связи для SQL Server , но этот поиск - абсолютный пожар. Заголовок моего запроса был «dmv для сопоставления временной таблицы с session_id» - поскольку поиск может выполнять только ИЛИ, «сопоставить временную таблицу» возвращает 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)
Бесстыдно взято из этого поста в блоге Джонатана Кехайяса .
Чтобы определить использование пространства, вы можете дополнительно улучшить это, чтобы объединить данные из представлений, таких как 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 мс после создание).
Некоторые другие ответы на этом сайте, которые могут быть полезны:
Я также написал в блоге об этом с помощью специального сеанса расширенных событий для отслеживания этой информации в SQL Server 2012 и более поздних версиях:
А Пол Уайт написал в блоге о чтении страниц напрямую (не для слабонервных и не может быть легко автоматизировано):