SQLServer 维护脚本分享(05)内存(Memory)

SQL Server 内存管理与优化详解
本文深入探讨了 SQL Server 中的内存管理机制,包括最大最小内存配置、系统物理内存使用情况、预留和提交内存情况等。通过提供详细的查询语句,帮助读者了解如何监控和优化内存使用,提升数据库性能。
--查看设置的最大最小每次
exec sp_configure 'max server memory (MB)'
exec sp_configure 'min server memory (MB)'


--SqlServer目标内存、当前内存 、数据库内存页数
SELECT object_name,counter_name,cntr_value,cntr_value/1024/1024 AS [cntr_value(GB)]
FROM sys.dm_os_performance_counters
WHERE counter_name in('Target Server Memory (KB)','Total Server Memory (KB)','Database pages')


--系统物理内存使用情况
SELECT * FROM sys.dm_os_sys_info
SELECT * FROM sys.dm_os_sys_memory
SELECT * FROM sys.dm_os_process_memory

--查看当前是否有等待内存授予的进程
Select a.*,b.text, c.query_plan 
from sys.dm_exec_query_memory_grants a
CROSS APPLY sys.dm_exec_sql_text(sql_handle) b 
CROSS APPLY sys.dm_exec_query_plan (plan_handle) c


--SqlServer预留和提交内存情况
DBCC MEMORYSTATUS; --旧的方法

SELECT  [type]   
,SUM(virtual_memory_reserved_kb) AS [vm reserved]  
,SUM(virtual_memory_committed_kb) AS [vm commited]  
,SUM(awe_allocated_kb) AS [awe allocated]    
,SUM(shared_memory_reserved_kb) AS [sm reserved]  
,SUM(shared_memory_committed_kb) AS [sm committed]  
,SUM(single_pages_kb) AS [Stolen in Buffer Pool]  
,SUM(multi_pages_kb) AS [MemToLeave]  
,SUM(single_pages_kb) + SUM(multi_pages_kb) AS [Stolen]  
,SUM(virtual_memory_committed_kb) + SUM(multi_pages_kb) AS [Buffer Pool]  
FROM sys.dm_os_memory_clerks 
GROUP BY [type]  
ORDER BY [type] desc


--当前各数据库buffer pool的分配情况
SELECT 
CASE database_id 
	WHEN 32767 THEN 'ResourceDb' 
	ELSE db_name(database_id) END AS Database_name
,count(*) AS cached_pages_count
,count(*)*8/1024 AS cached_space_in_mb
,sum(convert(bigint,free_space_in_bytes))/1024/1024 AS free_space_in_mb
FROM sys.dm_os_buffer_descriptors(nolock)
GROUP BY db_name(database_id) ,database_id
ORDER BY cached_pages_count DESC;


--当前数据库各表buffer pool的分配情况
SELECT top(20) name ,index_id ,count(*)AS cached_pages_count 
,count(*)*8/1024 AS cached_space_in_mb 
FROM sys.dm_os_buffer_descriptors AS bd 
INNER JOIN (
    SELECT object_name(object_id) AS name ,index_id ,allocation_unit_id
    FROM sys.allocation_units AS au INNER JOIN sys.partitions AS p 
    ON au.container_id = p.hobt_id  AND (au.type = 1 OR au.type = 3 ) 
    UNION ALL
    SELECT object_name(object_id) AS name,index_id, allocation_unit_id
    FROM sys.allocation_units AS au INNER JOIN sys.partitions AS p 
    ON au.container_id = p.hobt_id  AND au.type = 2
) AS obj ON bd.allocation_unit_id = obj.allocation_unit_id
WHERE database_id = db_id() AND obj.name NOT LIKE 'sys%'
GROUP BY name, index_id 
ORDER BY cached_pages_count DESC


-- 当前各表或索引在缓冲池中的页数量及大小
SELECT obj.name ,obj.index_id,i.name ,count(*)AS cached_pages_count ,count(*)*8/1024 AS cached_space_in_mb
FROM sys.dm_os_buffer_descriptors AS bd 
INNER JOIN (
	SELECT object_name(object_id) AS name,object_id,index_id ,allocation_unit_id
	FROM sys.allocation_units AS au
	INNER JOIN sys.partitions AS p ON au.container_id = p.hobt_id AND (au.type = 1 OR au.type = 3)
	UNION ALL
	SELECT object_name(object_id) AS name,object_id,index_id, allocation_unit_id
	FROM sys.allocation_units AS au
	INNER JOIN sys.partitions AS p   ON au.container_id = p.partition_id AND au.type = 2
) AS obj ON bd.allocation_unit_id = obj.allocation_unit_id
LEFT JOIN sys.indexes i(nolock) on obj.object_id = i.object_id AND obj.index_id = i.index_id  
WHERE database_id = db_id() AND obj.name NOT LIKE 'sys%'
GROUP BY obj.name ,obj.index_id,i.name
ORDER BY cached_pages_count DESC;

-- 统计当前内存分配情况
select 
physical_memory_in_bytes / 1024 / 1024 as physical_memory_mb,
virtual_memory_in_bytes / 1024 / 1024 as virtual_memory_mb,
bpool_committed * 8 / 1024 as bpool_committed_mb,
bpool_commit_target * 8 / 1024 as bpool_target_mb,
bpool_visible * 8 / 1024 as bpool_visible_mb
from sys.dm_os_sys_info


--当前内存脏页数量及大小
SELECT db_name(database_id) AS 'Database'
,count(page_id) AS 'Dirty Pages'
,count(page_id)*8/1024 AS 'Dirty Pages(MB)'
FROM sys.dm_os_buffer_descriptors(nolock)
WHERE is_modified =1
GROUP BY db_name(database_id)
ORDER BY 'Dirty Pages' DESC


--缓存类型数量大小
select cacheobjtype as [Cached Type]
,COUNT(*) [Number of Plans] 
,SUM(CONVERT(BIGINT,size_in_bytes))/1024/1024 [Plan Cache Size(MB)]
from sys.dm_exec_cached_plans 
group by cacheobjtype 
order by [Plan Cache Size(MB)] desc


--缓存对象数量大小
select objtype as [Cached Object Type]
,COUNT(*) as [Number of Plans] 
,SUM(CONVERT(BIGINT,size_in_bytes))/1024/1024 [Plan Cache Size(MB)]
,avg(usecounts) [Avg Use Count] 
from sys.dm_exec_cached_plans 
group by objtype 
order by [Plan Cache Size(MB)] desc

--内存对象
SELECT top 10 * FROM sys.dm_os_memory_cache_counters(nolock)
ORDER BY entries_count DESC;

SELECT * FROM sys.dm_os_memory_clerks a
WHERE name='TokenAndPermUserStore'

SELECT * FROM sys.dm_os_memory_cache_entries(nolock)
WHERE [type]='USERSTORE_TOKENPERM' and name='TokenAndPermUserStore'


--缓存分析对象
SELECT * FROM sys.syscacheobjects 
SELECT * FROM sys.dm_exec_cached_plans


--即时查询优化(运行即生效)
EXEC sp_configure 'show advanced options',1
RECONFIGURE
EXEC sp_configure 'optimize for ad hoc workloads',1
RECONFIGURE

SQL Server运行脚本一直处于处理中,可能由多种原因导致,以下是一些常见的解决方法: ### 检查锁和阻塞 锁和阻塞可能会导致脚本无法正常执行。可以使用以下查询来查看当前的锁和阻塞情况: ```sql -- 查看当前的阻塞情况 SELECT blocking_session_id, session_id, wait_type, wait_time, wait_resource FROM sys.dm_exec_requests WHERE blocking_session_id != 0; -- 查看当前的锁信息 SELECT resource_type, resource_database_id, resource_description, request_mode, request_status FROM sys.dm_tran_locks; ``` 如果发现有阻塞的会话,可以使用`KILL`命令终止阻塞会话: ```sql KILL <blocking_session_id>; ``` ### 检查资源使用情况 资源不足(如CPU、内存、磁盘I/O)也可能导致脚本执行缓慢或一直处于处理中。可以使用SQL Server Management Studio(SSMS)中的性能监视器或动态管理视图(DMV)来检查资源使用情况: ```sql -- 查看CPU使用情况 SELECT sql_text.text, cpu_time FROM sys.dm_exec_query_stats CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sql_text ORDER BY cpu_time DESC; -- 查看内存使用情况 SELECT * FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESC; -- 查看磁盘I/O使用情况 SELECT DB_NAME(database_id) AS database_name, file_id, io_stall_read_ms, num_of_reads, io_stall_write_ms, num_of_writes FROM sys.dm_io_virtual_file_stats(NULL, NULL); ``` 如果发现资源不足,可以考虑升级硬件或优化查询。 ### 优化查询 复杂或低效的查询可能会导致脚本执行缓慢。可以使用查询分析器来分析查询的执行计划,找出性能瓶颈并进行优化: ```sql -- 显示查询执行计划 SET SHOWPLAN_ALL ON; -- 执行你的查询 SELECT * FROM your_table; SET SHOWPLAN_ALL OFF; ``` 根据执行计划,可以考虑添加索引、优化查询语句结构、避免全表扫描等。 ### 检查事务状态 未提交或未回滚的事务可能会导致锁和阻塞。可以使用以下查询来查看当前的事务状态: ```sql SELECT transaction_id, transaction_state, transaction_begin_time FROM sys.dm_tran_active_transactions; ``` 如果发现有未提交或未回滚的事务,可以使用`COMMIT`或`ROLLBACK`命令处理: ```sql -- 提交事务 COMMIT TRANSACTION; -- 回滚事务 ROLLBACK TRANSACTION; ``` ### 重启SQL Server服务 在某些情况下,重启SQL Server服务可以解决一些临时的问题。可以通过服务管理器或命令行来重启服务: ```powershell # 停止SQL Server服务 Stop-Service -Name MSSQLSERVER; # 启动SQL Server服务 Start-Service -Name MSSQLSERVER; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值