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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

--查看设置的最大最小每次
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

<think>嗯,用户问的是SQL Server生成脚本带数据失败的问题。首先,我需要回忆一下生成数据脚本的常见方法,比如使用SSMS的生成脚本向导,或者sqlpackage工具。然后,导致失败的可能原因有哪些呢?可能有权限问题,数据量太大导致超时,数据类型不兼容,比如有二进制大对象或者CLR类型,还有外键约束或者触发器干扰。 接下来,解决步骤需要分点说明。首先检查报错信息,这是关键。然后调整生成选项,比如每表数据行数限制,脚本模式改为数据和架构,处理大对象数据可能需要单独导出。接着,使用命令行工具sqlpackage,这样可能更稳定,特别是对于大数据量。如果数据量实在太大,可能需要分批导出或者用BCP工具。另外,检查是否有不支持的数据类型,或者数据库状态是否正常,比如处于单用户模式。 还要提醒用户注意版本兼容性,高版本生成的低版本脚本可能有兼容问题。保持SSMS更新也是个好建议。可能用户在使用向导时没有正确选择导出数据的选项,或者遇到超时问题,这时候调整超时设置可能有帮助。总之,需要系统性地排除各种可能性,从简单到复杂逐步尝试。</think>在 SQL Server 中使用"生成脚本"功能导出数据失败时,可能涉及以下几个关键原因和解决方案: --- ### 一、常见错误原因 1. **权限不足** - 检查登录账号是否拥有对目标数据库的`SELECT`权限和`VIEW DEFINITION`权限 - 验证是否拥有访问`sys.objects`等系统视图的权限 2. **数据类型限制** - 不支持`varbinary(max)`, `FILESTREAM`, `CLR类型`等二进制数据的脚本生成 - 包含加密列的表无法生成数据脚本 3. **数据量过大** - 默认设置下单个脚本文件超过 80MB 可能导致生成失败 - 大文本字段(如`nvarchar(max)`)可能超出内存限制 4. **约束冲突** - 外键约束未正确排序导致插入顺序错误 - 存在触发器时可能干扰数据插入 --- ### 二、分步解决方案 #### 步骤 1:检查报错日志 在 SSMS 的"生成脚本向导"最后一步勾选「高级」→「错误时继续」→ **False**,获取具体错误信息 #### 步骤 2:调整生成选项 1. 在"设置脚本编写选项"界面点击「高级」 ```text 要编写的脚本的数据类型 → 架构和数据 脚本触发器和脚本外键 → 设为 False(临时禁用) 每表数据行数 → 调整为 1000(测试用) ``` 2. 对于大表: ```text 脚本日志记录 → False 统计信息 → 不编写统计信息脚本 ``` #### 步骤 3:使用命令行工具 通过`sqlpackage.exe`导出更稳定(位于SSMS安装目录): ```powershell sqlpackage.exe /Action:Export /ssn:服务器名 /sdn:数据库名 /su:用户名 /sp:密码 /tf:导出文件路径.dacpac ``` #### 步骤 4:分批导出数据 对超过 100 万行的大表使用`BCP`工具: ```cmd bcp "SELECT * FROM 大表名" queryout 数据文件.dat -S 服务器名 -d 数据库名 -U 用户名 -P 密码 -n ``` --- ### 三、特殊场景处理 1. **二进制数据导出** - 使用`OPENROWSET(BULK...)`单独导出BLOB字段 ```sql INSERT INTO 表名(文件列) SELECT BulkColumn FROM OPENROWSET(BULK N'C:\file.pdf', SINGLE_BLOB) AS doc ``` 2. **内存优化表** - 需先禁用内存优化功能: ```sql ALTER DATABASE 当前数据库 SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = OFF ``` --- ### 四、验证脚本完整性 1. 检查生成的`.sql`文件是否包含: ```sql SET IDENTITY_INSERT 表名 ON; INSERT INTO 表名 (...) VALUES (...); SET IDENTITY_INSERT 表名 OFF; ``` 2. 使用`SQLCMD`模式执行测试: ```cmd sqlcmd -S 服务器名 -d 目标库 -i 脚本文件.sql -o 执行日志.txt ``` --- ### 注意事项 - 当导出超过 1GB 数据时,建议优先使用`备份还原`或`SSIS`工具 - SQL Server 2016 及以上版本对JSON格式数据导出有更好支持 - 导出前建议运行`DBCC CHECKDB`确保数据库一致性 如果问题仍未解决,请提供具体错误代码和表结构信息,可进一步分析数据冲突或索引异常等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值