Tìm phiên nào đang giữ bảng tạm thời


14

Chúng tôi có cơ sở dữ liệu SQL Server 2005, cơ sở dữ liệu tạm thời đã đầy đủ. Bằng cách vào SQL Server Management Studio, tôi có thể thấy tất cả các bảng tạm thời trong tempdb. Có thể cho biết phiên nào đang giữ bảng tạm thời? Lý tưởng nhất là một truy vấn sẽ liệt kê các bảng tạm thời được sử dụng bởi mỗi phiên.

Cảm ơn,


1
Chúng tôi muốn theo dõi người dùng cụ thể đang sử dụng không gian trong cơ sở dữ liệu tạm thời. Đó là mức tiêu thụ tempdb của các tác vụ hiện tại mà chúng tôi quan tâm.
SQLMIKE

Câu trả lời:


16

Tôi đã yêu cầu một cái gì đó được xây dựng trở lại vào năm 2007, trên Connect. Điều này đã bị từ chối cho phiên bản 2008 và sau đó bị bỏ qua, cho đến khi Connect chết vài năm trước. Tôi đã cố gắng tìm nó trên trang web phản hồi mới cho SQL Server , nhưng tìm kiếm đó là một đám cháy tuyệt đối. Tiêu đề yêu cầu của tôi là "dmv để ánh xạ bảng tạm thời sang session_id" - vì việc tìm kiếm chỉ có thể thực hiện HOẶC, "bảng tạm thời bản đồ" trả về 118 trang kết quả. Google dường như đề xuất mặt hàng không thực hiện việc cắt giảm khi họ giết Connect .

Trong khi đó, đối với SQL Server 2005 và 2008, bạn sẽ có thể lấy thông tin này từ theo dõi mặc định:

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)

Không biết xấu hổ nhấc lên từ bài viết trên blog Jonathan Kehayias này .

Để xác định mức sử dụng không gian, bạn có thể tăng cường hơn nữa để tham gia dữ liệu từ các chế độ xem như sys.db_db_partition_stats- ví dụ:

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)

Vấn đề ở đây là cố gắng tương quan tên bảng bằng văn bản truy vấn; điều này không thực tế, vì hầu hết thời gian, người dùng vẫn không thực hiện truy vấn đối với bảng đó (không bao giờ để ý chạy cái đã tạo / điền vào nó).

Tuy nhiên, và điều này là dành cho những người đọc khác (hoặc cho bạn khi bạn nâng cấp), theo dõi mặc định trong năm 2012+ không còn theo dõi việc tạo đối tượng bảng tạm thời , nếu bảng #temp là một đống. Không chắc chắn nếu đó là một sự trùng hợp ngẫu nhiên hoặc liên quan trực tiếp đến thực tế là bắt đầu từ năm 2012, tất cả các bảng tạm thời đều có kết quả âmobject_id . Tất nhiên bạn có thể chuyển đến Sự kiện mở rộng để giúp bạn thu thập và theo dõi thông tin này, nhưng đó có thể là rất nhiều công việc thủ công (và tôi chỉ xác minh rằng điều này không còn được theo dõi trong dấu vết - bạn có thể không chọn được trong các sự kiện mở rộng hoặc). Theo dõi mặc định sẽ chọn các bảng #temp được tạo bằng PK hoặc các ràng buộc khác hoặc với các ràng buộc hoặc chỉ mục được thêm vào sau sự kiện tạo, nhưng sau đó bạn sẽ phải nới lỏng các hạn chế dựa trên thời gian ở trên (một chỉ mục có thể được tạo muộn hơn 100ms sau sự sáng tạo).

Một số câu trả lời khác trên trang web này có thể hữu ích:

Tôi cũng đã viết blog về điều này, với phiên Sự kiện mở rộng tùy chỉnh để theo dõi thông tin này trong SQL Server 2012 trở lên:

Và Paul White đã viết blog về việc đọc các trang trực tiếp (không chính xác cho người yếu tim, cũng không dễ tự động hóa theo bất kỳ cách nào):


5

Đây là một truy vấn sẽ giúp bạn bắt đầu tìm hiểu thông tin bạn đang tìm kiếm:

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;

Truy vấn này lấy thông tin hữu ích cho 10 tác vụ hàng đầu, chẳng hạn như các trang được phân bổ / giải quyết, văn bản SQL của các tác vụ (nếu có), v.v.

Các DMV này có đầy đủ thông tin tuyệt vời, vì vậy nếu bạn cần thêm dữ liệu thì bạn có thể trộn và khớp với những gì bạn đang kéo. Nhưng đây phải là điểm khởi đầu để khắc phục các tác vụ tiêu thụ tempdb hiện tại.


Cảm ơn có vẻ khá tốt. Điều kỳ lạ là nếu tôi chạy báo cáo 'Sử dụng đĩa theo bảng trên cùng' trên tempdb, bảng đang sử dụng nhiều không gian nhất sẽ không xuất hiện trong st.text. Bảng vẫn còn đó sau khi tôi chạy truy vấn.
SQLMIKE

1
@QueryMIKE nếu bạn chỉ muốn biết bảng nào là lớn nhất, bạn có thể lấy bảng đó từ tempdb.sys.dm_db_partition_stats. Thật không may, bạn thực sự không thể biết bản sao nào #some_table_namethuộc về người dùng nào, và bạn sẽ không thể kéo văn bản câu lệnh tham chiếu bảng đó vào bất kỳ thời điểm nào - đó có thể không phải là truy vấn mà người dùng hiện đang chạy. Bạn có thể muốn thấy cái nàycái này
Aaron Bertrand
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.