Tempdb--monitoring and troubleshooting

TempDB用来存放临时表、全局临时表、表变量以及排序或HASH等操作引发的中间结果集

 

TempDB在每次实例重启时重新创建,TempDB数据库文件的初始化大小取决于Model数据库的文件大小或显示ALTER语句设置的TempDB的文件文件大小

 

在每个数据库文件中,分配页(allocation page)ID:

PFS:1

GAM:2

SGAM:3

 

一个PFS页能覆盖8088个数据页,一个GAM或SGAM页能覆盖511232个数据页,当一个文件超过响应数据页数,SQL SERVER 使用分配页(allocation page)链来覆盖。

 

---------------------------------------------------------------------------------

由于临时表和表变量创建和销毁时,需要锁住分配页来为临时表或表变量分配数据页,当创建和销毁的过于频繁时,会造成ALLOCATION BOTTLENECK

 

查看是否是Allocation BottleNeck:

 

SELECT *

FROM sys.dm_os_waiting_tasks

WHERE wait_type LIKE 'PAGE%LATCH_%'

AND resource_description LIKE '2:%'

 

解决ALLOCATION BOTTLENECK的方法:

1. 建立与CORE或CPU相同个数的物理文件数

2. 使用TF1118(SQL SERVER 2005后),为新对象分配数据页时分配到新数据区而不使用混合区,减少SGAM的争用

 

 

---------------------------------------------------------------------------------

 

由于临时表和表变量创建和销毁时,需要对相关系统表插入或删除该临时表的元数据信息,当创建和销毁的过于频繁时,便会造成DDL BottleNeck

 

查看DDL BottleNeck:

SELECT *

FROM sys.dm_os_waiting_tasks

WHERE wait_type LIKE 'PAGE%LATCH_%'

AND resource_description LIKE '2:%'

 

查看DDL BottleNeck和查看Allocation BottleNeck的脚本一样,但是两者锁定的资源不一样

 

或使用性能计数器来判断:

 

SELECT * FROM sys.dm_os_performance_counters

WHERE counter_name LIKE '%temp%table%'

 

'Active Temp Tables':当前使用中的临时表

'Temp Tables Creation Rate':每秒创建的临时表或表变量的个数

'Temp Tables For Destruction':等待系统进程清理的表变量或临时表的个数

 

当'Temp Tables Creation Rate'和'Temp Tables For Destruction'值较高时,则可能存在DDL BottleNeck

 

解决方案:

1. 将频繁创建和删除的临时表或表变量改为用户表

 

---------------------------------------------------------------------------------

 

在TempDB上,由于某些不合理的执行计划和SQL消耗大量的空间,造成Space BottleNeck

 

查看Space BottleNeck:

 

-- This DMV query shows currently executing tasks and 

-- tempdb space usage

-- Once you have isolated the task(s) that are generating lots 

-- of internal object allocations, 

-- you can even find out which TSQL statement and its query plan 

-- for detailed analysis

 

 

SELECT TOP 10

t1.session_id, 

t1.request_id, 

t1.task_alloc,

t1.task_dealloc,  

(

SELECT SUBSTRING(TEXT, t2.statement_start_offset/2 + 1,

(CASE WHEN statement_end_offset = -1 

      THEN LEN(CONVERT(NVARCHAR(MAX),TEXT)) * 2 

           ELSE statement_end_offset 

      END - t2.statement_start_offset)/2)

  FROM sys.dm_exec_sql_text(sql_handle)

) AS query_text,

(SELECT query_plan FROM sys.dm_exec_query_plan(t2.plan_handle)) AS query_plan

FROM      

(SELECT session_id, request_id,

SUM(internal_objects_alloc_page_count +   user_objects_alloc_page_count) AS task_alloc,

SUM (internal_objects_dealloc_page_count + user_objects_dealloc_page_count) AS task_dealloc

       FROM sys.dm_db_task_space_usage 

       GROUP BY session_id, request_id

) AS t1, 

sys.dm_exec_requests AS t2

WHERE t1.session_id = t2.session_id AND 

(t1.request_id = t2.request_id) AND 

      t1.session_id > 50

ORDER BY t1.task_alloc DESC

 

解决方案:

1. 找出耗空间较大的SQL并优化

 

---------------------------------------------------------------------------------

 

参考:

http://blogs.msdn.com/b/sqlserverstorageengine/archive/2009/01/12/tempdb-monitoring-and-troubleshooting-out-of-space.aspx

原文地址:https://www.cnblogs.com/TeyGao/p/3519613.html