首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

SQL Server由内存引发的性能有关问题(紧急)

2013-10-18 
SQL Server由内存引发的性能问题(紧急,在线等)大家好。我的数据库使用的是SQL Server 2008 R2,现在出现了一

SQL Server由内存引发的性能问题(紧急,在线等)
大家好。

我的数据库使用的是SQL Server 2008 R2,现在出现了一点问题。数据库这段时间运行一直很正常,可从今天起开始出现了严重的性能问题,读取数据非常的慢。打开活动监视器后,发现数据库I/O平均在60M每秒(在正常时平均1M每秒左右)。我对SQL Server不是很懂,别人告诉我有可能是内存问题,我在服务器属性中查到设置的最大服务器内存为我的服务器内存(接近16G),于是我把它改成了12G,结果性能立即恢复正常。可是过了一段时间以后,同样的性能问题又出现了,数据库I/O又达到了60M每秒左右,这时我再次随意调整了一下最大服务器内存(改为10G以后又改回12G),结果性能再次立即恢复正常。于是,今天我的系统像过山车一样,每隔几十分钟,当出现性能问题以后,我就调整下内存设置。一直到我发帖时 :-(

请大家帮忙分析一下,太高深的东西对我这个菜鸟来说可能不太好理解,如可能的话请指导一下如何解决或点明一个方向,非常感谢!
[解决办法]
设为自动分配内存试试.

另.检查SQL2008R2 SP2补丁安装了没.
[解决办法]
查PAGEFILE的使用,用性能监视器查IO内存 CPU ,另外SQL部分也查一下为什么有大的IO发生
[解决办法]
突然之间,IO量暴增,肯定是由于有什么语句需要查询大量的数据,或者是执行了什么批量化的修改,删除操作。
但就像你说的,为什么调整了内存后,又正常了,这个应该还是和内存有关系。

先大概了解一下内存的使用情况,特别是里面的SinglePage和MultiPage,看看哪部分消耗比较多。

单页一般用于缓存数据,和一些简单的查询语句和执行计划,还有网络包等等。
多页一般用于非常复杂的sql语句,也就是超过了8k的语句,以及SQL Server本身的线程代码所需的内存,还有扩展存储过程xp_开头的存储过程,CLR存储过程,SP_OACreate等。

检查SQL Server的内存使用情况

select 
    type,
    
sum(virtual_memory_reserved_kb) as [VM Reserved],   --从buffer pool中保留的大小

sum(virtual_memory_committed_kb) as [VM Committed], --从buffer pool中提交的大小

--是Buffer Pool里的Stolen Memory的大小.在Buffer Pool中通过Stolen分配的,也就是直接Commit分配的内存量.
sum(single_pages_kb) as [SinlgePage Allocator],

--分配的多页内存量(KB),是使用内存节点的多页分配器分配的内存量。此内存在buffer pool外分配,是SQL Server自己的代码使用的MemToLeave大小。
sum(multi_pages_kb) as [MultiPage Allocator],

--内存Clerk使用地址窗口化扩展插件(AWE)分配的内存量。当启用AWE时,只有缓冲池Clerk(MEMORYCLERK_SQLBUFFERPOOL)使用此机制,不可为空值。
    --可以由buffer pool使用的内存量
sum(awe_allocated_kb) as [AWE Allocated],

sum(shared_memory_reserved_kb) as [SM Reserved],   --内存Clerk保留的共享内存量,保留给共享内存和文件映射使用.

sum(shared_memory_committed_kb) as [SM Committed]  --内存Clerk提交的共享内存量,和上面的字段一起可以追踪Shared Memory的大小.

from sys.dm_os_memory_clerks 
group by type
order by type


具体的,查询是由哪些语句,导致那么多的IO,特别是物理读(IO有关)和逻辑读:

--3.3 使用DMV分析SQL Server启动以来做read最多的语句

--3.3.1 按照物理读的页面数排序,前50名。
SELECT TOP 50
qs.total_physical_reads,
qs.execution_count,
    qs.total_physical_reads /qs.execution_count as [Avg Physical Read IO],
    
    qs.sql_handle,
qs.plan_handle,
qs.statement_start_offset,  --以字节为单位,但是text字段为nvarchar类型,也就是一个字符占用2个字节
qs.statement_end_offset,

qt.dbid, 
dbname=db_name(qt.dbid),
qt.objectid,               --只有procedure,trigger,view,function才会有对象id

    SUBSTRING( qt.text,
               qs.statement_start_offset / 2, 
           (case when qs.statement_end_offset = -1 
              then len(convert(nvarchar(max), qt.text)) * 2  
         else qs.statement_end_offset 
    end - qs.statement_start_offset ) / 2  + 1
 ) as query_text
 
FROM sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
--where qt.text like '%select * from dbo.base_org%'
ORDER BY qs.total_physical_reads desc



--3.3.2 按照逻辑读的页面数排序,前50名。
SELECT TOP 50
qs.total_logical_reads,qs.execution_count,
    qs.total_logical_reads /qs.execution_count as [Avg Logical Read IO],
    
    qs.sql_handle,
qs.plan_handle,
qs.statement_start_offset,  --以字节为单位,但是text字段为nvarchar类型,也就是一个字符占用2个字节
qs.statement_end_offset,

qt.dbid, 
dbname=db_name(qt.dbid),
qt.objectid,               --只有procedure,trigger,view,function才会有对象id

--这里必须要加1,因为有时statement_start_offset为0,那么需要取的长度要加上1,否则取出来的就会少一个字符
--如: select substring('abc',0,3) 会输出'ab',所以要写成:select substring('abc',0,3 + 1)
    SUBSTRING( qt.text,
               qs.statement_start_offset / 2,
               case when qs.statement_end_offset = -1


                         then (datalength(cast(qt.text as nvarchar(max))) - qs.statement_start_offset ) / 2+ 1
                    else (qs.statement_end_offset - qs.statement_start_offset) / 2 + 1
               end
             ) as query_text
FROM sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY qs.total_logical_reads desc
     


[解决办法]
1、查看等待信息:
SELECT * FROM sys.dm_os_waiting_tasks ORDER BY wait_duration_ms DESC 
SELECT * FROM sys.dm_os_wait_stats ORDER BY wait_time_ms DESC
 
2、开启性能监视器监控CPU、内存、磁盘的队列性能
[解决办法]
两方面,IO到60肯定是有大查询,如果再到这个级别就用楼上各位提供的方式查一下查询内容和来源;改完内存变快这个真不知道为什么,可能是因为修改完内存SQL会自动做一遍内存清理空出些地方吧
[解决办法]
看现象,很可能是设置了一个较大的虚拟内存,而且磁盘i/o速度又较慢,建议查下虚拟内存设置,修改为1-2g就够了

热点排行