1. 首页 > SQLServer教程 > 正文

SQLServer教程FG071-SQLServer连接池优化实战

本文档风哥主要介绍SQLServer数据库连接池优化相关知识,包括SQLServer数据库连接池的概念、SQLServer数据库连接池工作原理、SQLServer数据库连接池核心参数配置、SQLServer数据库连接池监控与问题排查等内容,风哥教程参考SQLServer官方文档Database Engine、Administration内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

Part01-基础概念与理论知识

1.1 SQLServer数据库连接池概念

SQLServer数据库连接池(Connection Pool)是一种数据库连接管理机制,通过预先创建并维护一定数量的数据库连接,避免频繁创建和销毁连接带来的性能开销。连接池在应用程序和数据库之间充当中间层,有效提升系统性能和资源利用率。更多视频教程www.fgedu.net.cn

SQLServer数据库连接池的特点:

  • 减少连接创建开销,提升响应速度
  • 控制并发连接数,保护数据库资源
  • 连接复用,降低系统负载
  • 支持连接验证和健康检查
  • 提供连接超时和等待队列机制

1.2 SQLServer数据库连接池工作原理

SQLServer数据库连接池工作原理:

  • 连接创建:应用程序首次请求连接时,连接池创建新连接
  • 连接复用:连接使用完毕后归还池中,供其他请求复用
  • 连接验证:从池中获取连接时验证连接有效性
  • 连接回收:空闲超时的连接被自动回收销毁
  • 连接扩展:连接不足时按需创建新连接至最大值
# SQLServer连接池工作流程示意

应用程序请求连接
|
v
+——————+
| 连接池检查 |
+——————+
|
+– 有空闲连接 –> 验证连接 –> 返回连接
|
+– 无空闲连接 –> 创建新连接(未达最大值) –> 返回连接
|
+– 已达最大值 –> 等待队列 –> 超时报错

应用程序释放连接
|
v
+——————+
| 连接归还池中 |
+——————+
|
+– 空闲超时 –> 销毁连接
|
+– 未超时 –> 保留待复用

1.3 SQLServer数据库连接池核心参数

SQLServer数据库连接池核心参数说明:

# ADO.NET连接池核心参数
Min Pool Size 最小连接数,默认0
Max Pool Size 最大连接数,默认100
Connect Timeout 连接超时时间,默认15秒
Connection Lifetime 连接生命周期,默认0(无限)
Pooling 是否启用连接池,默认true
Connection Reset 连接重置,默认true

# JDBC连接池核心参数
maxPoolSize 最大连接数
minPoolSize 最小连接数
acquireIncrement 连接增长步长
maxIdleTime 最大空闲时间
checkoutTimeout 获取连接超时时间
idleConnectionTestPeriod 空闲连接检测周期

# SQLServer服务器端参数
user connections 最大用户连接数,默认32767
max worker threads 最大工作线程数,默认0(自动)

风哥提示:连接池参数配置需要根据实际业务并发量、数据库服务器配置、网络环境等因素综合考虑。建议在测试环境充分验证后再应用到生产环境。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 SQLServer数据库连接池规划

SQLServer数据库连接池规划要点:

# 连接池大小规划公式
最小连接数 = 核心业务并发数 × 1.2
最大连接数 = 峰值业务并发数 × 1.5

# 不同场景规划建议
小型应用(并发<50): Min Pool Size: 5 Max Pool Size: 50 中型应用(并发50-200): Min Pool Size: 20 Max Pool Size: 150 大型应用(并发200-500): Min Pool Size: 50 Max Pool Size: 300 超大型应用(并发>500):
Min Pool Size: 100
Max Pool Size: 500

# 注意事项
– 最大连接数不超过服务器user connections配置
– 考虑多应用实例共享数据库的情况
– 预留管理连接和系统连接
– 考虑连接泄漏的缓冲空间

2.2 SQLServer数据库连接池配置建议

SQLServer数据库连接池配置建议:

# ADO.NET连接字符串配置示例
Server=192.168.1.100;Database=fgedudb;
User ID=fgedu;Password=fgedu123;
Min Pool Size=20;
Max Pool Size=150;
Connect Timeout=30;
Connection Lifetime=600;
Pooling=true;

# JDBC连接池配置示例(c3p0)
jdbcUrl=jdbc:sqlserver://192.168.1.100:1433;databaseName=fgedudb
user=fgedu
password=fgedu123
minPoolSize=20
maxPoolSize=150
acquireIncrement=10
maxIdleTime=600
checkoutTimeout=30000
idleConnectionTestPeriod=60

# HikariCP连接池配置示例
jdbcUrl=jdbc:sqlserver://192.168.1.100:1433;databaseName=fgedudb
username=fgedu
password=fgedu123
minimumIdle=20
maximumPoolSize=150
connectionTimeout=30000
idleTimeout=600000
maxLifetime=1800000

2.3 SQLServer数据库连接池监控策略

SQLServer数据库连接池监控策略:

  • 连接数监控:监控当前连接数、活跃连接数、空闲连接数
  • 等待监控:监控连接等待时间、等待队列长度
  • 错误监控:监控连接超时、连接失败次数
  • 性能监控:监控连接获取时间、连接使用时长
  • 资源监控:监控数据库服务器CPU、内存、网络
生产环境建议:建立完善的连接池监控体系,设置合理的告警阈值,定期分析连接池使用情况,及时发现和解决连接池问题。学习交流加群风哥QQ113257174

Part03-生产环境项目实施方案

3.1 SQLServer数据库连接池状态查看

3.1.1 SQLServer数据库查看当前连接数

# 查看当前所有连接
SELECT
DB_NAME(dbid) AS DatabaseName,
COUNT(*) AS ConnectionCount,
hostname AS HostName,
program_name AS ProgramName,
loginame AS LoginName
FROM sys.sysprocesses
WHERE dbid > 0
GROUP BY DB_NAME(dbid), hostname, program_name, loginame
ORDER BY ConnectionCount DESC;
GO

DatabaseName ConnectionCount HostName ProgramName LoginName
———— ————— —————- ——————– ———-
fgedudb 85 APP-SERVER-01 .Net SqlClient fgedu
fgedudb 42 APP-SERVER-02 .Net SqlClient fgedu
master 5 DB-SERVER-01 Microsoft SQL Server sa
fgedudb 3 APP-SERVER-03 JDBC-SQLServer fgedu

# 查看详细连接信息
SELECT
session_id,
DB_NAME(database_id) AS DatabaseName,
host_name,
program_name,
login_name,
status,
cpu_time,
memory_usage,
total_scheduled_time,
total_elapsed_time,
last_request_start_time,
last_request_end_time
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
ORDER BY session_id;
GO

session_id DatabaseName host_name program_name login_name status cpu_time memory_usage
———- ———— ————- —————- ———- —— ———- ———–
51 fgedudb APP-SERVER-01 .Net SqlClient fgedu running 125 2
52 fgedudb APP-SERVER-01 .Net SqlClient fgedu sleeping 0 1
53 fgedudb APP-SERVER-02 .Net SqlClient fgedu running 89 2
54 fgedudb APP-SERVER-02 .Net SqlClient fgedu sleeping 0 1

3.1.2 SQLServer数据库查看连接配置

# 查看最大连接数配置
EXEC sp_configure ‘user connections’;
GO

name minimum maximum config_value run_value
——————– ——— ———– ———— ———
user connections 0 32767 0 32767

# 查看当前连接数统计
SELECT
@@MAX_CONNECTIONS AS MaxConnections,
@@CONNECTIONS AS TotalConnectionsSinceStartup,
(SELECT COUNT(*) FROM sys.dm_exec_sessions) AS CurrentSessions,
(SELECT COUNT(*) FROM sys.dm_exec_connections) AS CurrentConnections;
GO

MaxConnections TotalConnectionsSinceStartup CurrentSessions CurrentConnections
————– —————————- ————— —————–
32767 1523456 135 132

# 查看工作线程配置
EXEC sp_configure ‘max worker threads’;
GO

name minimum maximum config_value run_value
——————– ——— ———– ———— ———
max worker threads 128 65535 0 512

3.2 SQLServer数据库连接池优化配置

3.2.1 SQLServer数据库服务器端优化

# 配置最大用户连接数
EXEC sp_configure ‘user connections’, 500;
RECONFIGURE;
GO

Configuration option ‘user connections’ changed from 0 to 500.
Run the RECONFIGURE statement to install.

# 配置最大工作线程数
EXEC sp_configure ‘max worker threads’, 1024;
RECONFIGURE;
GO

Configuration option ‘max worker threads’ changed from 0 to 1024.
Run the RECONFIGURE statement to install.

# 查看配置生效情况
EXEC sp_configure ‘user connections’;
EXEC sp_configure ‘max worker threads’;
GO

name minimum maximum config_value run_value
——————– ——— ———– ———— ———
user connections 0 32767 500 500
max worker threads 128 65535 1024 1024

3.2.2 SQLServer数据库连接超时优化

# 查看远程登录超时配置
EXEC sp_configure ‘remote login timeout (s)’;
GO

name minimum maximum config_value run_value
————————– ——— ———– ———— ———
remote login timeout (s) 0 2147483647 10 10

# 设置远程登录超时时间
EXEC sp_configure ‘remote login timeout (s)’, 30;
RECONFIGURE;
GO

Configuration option ‘remote login timeout (s)’ changed from 10 to 30.
Run the RECONFIGURE statement to install.

# 查看查询等待配置
EXEC sp_configure ‘query wait (s)’;
GO

name minimum maximum config_value run_value
——————– ——— ———– ———— ———
query wait (s) -1 2147483647 -1 -1

3.3 SQLServer数据库连接池问题排查

3.3.1 SQLServer数据库排查连接等待问题

# 查看等待连接的会话
SELECT
session_id,
wait_type,
wait_time,
wait_resource,
DB_NAME(database_id) AS DatabaseName,
host_name,
program_name,
status
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
WHERE wait_type LIKE ‘%CONNECT%’ OR wait_type LIKE ‘%LOGIN%’
ORDER BY wait_time DESC;
GO

session_id wait_type wait_time wait_resource DatabaseName host_name program_name status
———- —————– ——— —————– ———— ————- ————– ——-
125 SOS_SCHEDULER_YIELD 15000 fgedudb APP-SERVER-01 .Net SqlClient running
126 RESOURCE_SEMAPHORE 12000 fgedudb APP-SERVER-02 .Net SqlClient running

# 查看连接相关等待统计
SELECT
wait_type,
waiting_tasks_count,
wait_time_ms,
max_wait_time_ms,
signal_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type IN (
‘SOS_SCHEDULER_YIELD’,
‘RESOURCE_SEMAPHORE’,
‘THREADPOOL’,
‘CMEMTHREAD’,
‘CXPACKET’
)
ORDER BY wait_time_ms DESC;
GO

wait_type waiting_tasks_count wait_time_ms max_wait_time_ms signal_wait_time_ms
——————– ——————- ———— —————- ——————-
SOS_SCHEDULER_YIELD 125678 5678900 45000 123456
RESOURCE_SEMAPHORE 12345 1234567 30000 23456
THREADPOOL 5678 456789 25000 12345

风哥提示:当出现连接等待问题时,首先检查连接池配置是否合理,然后排查是否有连接泄漏或长连接占用资源。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 SQLServer数据库连接池耗尽案例

# 问题现象:应用程序报错”连接池已满”
# 错误信息:Timeout expired. The timeout period elapsed prior to
# obtaining a connection from the pool.

# 分析步骤:

# 1. 查看当前连接状态
SELECT
DB_NAME(dbid) AS DatabaseName,
COUNT(*) AS ConnectionCount,
status,
hostname
FROM sys.sysprocesses
WHERE dbid = DB_ID(‘fgedudb’)
GROUP BY DB_NAME(dbid), status, hostname
ORDER BY ConnectionCount DESC;
GO

DatabaseName ConnectionCount status hostname
———— ————— ——– ————
fgedudb 150 sleeping APP-SERVER-01
fgedudb 45 sleeping APP-SERVER-02
fgedudb 5 running APP-SERVER-01

# 2. 查看长时间空闲连接
SELECT
session_id,
DB_NAME(database_id) AS DatabaseName,
host_name,
program_name,
status,
DATEDIFF(MINUTE, last_request_end_time, GETDATE()) AS IdleMinutes,
last_request_end_time
FROM sys.dm_exec_sessions
WHERE database_id = DB_ID(‘fgedudb’)
AND status = ‘sleeping’
AND DATEDIFF(MINUTE, last_request_end_time, GETDATE()) > 30
ORDER BY IdleMinutes DESC;
GO

session_id DatabaseName host_name program_name status IdleMinutes last_request_end_time
———- ———— ————- ————– ——- ———– ——————–
78 fgedudb APP-SERVER-01 .Net SqlClient sleeping 125 2026-04-07 08:30:00
82 fgedudb APP-SERVER-01 .Net SqlClient sleeping 98 2026-04-07 08:57:00
95 fgedudb APP-SERVER-02 .Net SqlClient sleeping 67 2026-04-07 09:28:00

# 3. 解决方案:清理长时间空闲连接
— 创建清理脚本
DECLARE @sql NVARCHAR(MAX) = ”;
SELECT @sql = @sql + ‘KILL ‘ + CAST(session_id AS VARCHAR) + ‘; ‘
FROM sys.dm_exec_sessions
WHERE database_id = DB_ID(‘fgedudb’)
AND status = ‘sleeping’
AND DATEDIFF(MINUTE, last_request_end_time, GETDATE()) > 60;
EXEC(@sql);
GO

# 4. 优化连接池配置
— 应用端连接字符串调整
— Max Pool Size=200 (从150增加)
— Connection Lifetime=1800 (30分钟自动回收)
— Connection Reset=true (连接重置)

4.2 SQLServer数据库连接泄漏案例

# 问题现象:数据库连接数持续增长,最终达到上限

# 分析步骤:

# 1. 监控连接数变化
— 创建监控脚本
SELECT
GETDATE() AS CheckTime,
DB_NAME(database_id) AS DatabaseName,
COUNT(*) AS ConnectionCount,
SUM(CASE WHEN status = ‘running’ THEN 1 ELSE 0 END) AS ActiveCount,
SUM(CASE WHEN status = ‘sleeping’ THEN 1 ELSE 0 END) AS SleepingCount
FROM sys.dm_exec_sessions
WHERE database_id = DB_ID(‘fgedudb’)
GROUP BY DB_NAME(database_id);
GO

CheckTime DatabaseName ConnectionCount ActiveCount SleepingCount
———————– ———— ————— ———– ————-
2026-04-08 10:00:00 fgedudb 150 5 145
2026-04-08 11:00:00 fgedudb 180 8 172
2026-04-08 12:00:00 fgedudb 210 6 204
2026-04-08 13:00:00 fgedudb 245 7 238

# 2. 分析连接来源
SELECT
host_name,
program_name,
COUNT(*) AS ConnectionCount,
MIN(login_time) AS FirstLogin,
MAX(login_time) AS LastLogin
FROM sys.dm_exec_sessions
WHERE database_id = DB_ID(‘fgedudb’)
GROUP BY host_name, program_name
ORDER BY ConnectionCount DESC;
GO

host_name program_name ConnectionCount FirstLogin LastLogin
————- ————– ————— ——————— ———————
APP-SERVER-01 .Net SqlClient 180 2026-04-08 08:00:00 2026-04-08 13:00:00
APP-SERVER-02 .Net SqlClient 65 2026-04-08 08:05:00 2026-04-08 13:00:00

# 3. 排查应用代码问题
— 检查是否有未关闭的连接
— 确保使用using语句或try-finally关闭连接
— 检查连接池配置是否合理

# 4. 解决方案
— 应用代码修改示例(C#)
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
// 执行数据库操作
// 连接会自动关闭和释放
}

— 配置连接池参数
Min Pool Size=20
Max Pool Size=200
Connection Lifetime=1800
Connection Reset=true
Pooling=true

4.3 SQLServer数据库连接池优化方案

SQLServer数据库连接池优化综合方案:

# 1. 服务器端优化
— 配置合理的最大连接数
EXEC sp_configure ‘user connections’, 500;
RECONFIGURE;

— 配置工作线程数
EXEC sp_configure ‘max worker threads’, 1024;
RECONFIGURE;

— 配置内存
EXEC sp_configure ‘min server memory (MB)’, 4096;
EXEC sp_configure ‘max server memory (MB)’, 16384;
RECONFIGURE;

# 2. 应用端优化
— 连接字符串配置
Server=192.168.1.100;Database=fgedudb;
User ID=fgedu;Password=fgedu123;
Min Pool Size=20;
Max Pool Size=200;
Connect Timeout=30;
Connection Lifetime=1800;
Connection Reset=true;
Pooling=true;

# 3. 监控脚本
— 创建连接池监控存储过程
CREATE PROCEDURE sp_fgedu_monitor_connections
AS
BEGIN
SELECT
GETDATE() AS CheckTime,
DB_NAME(database_id) AS DatabaseName,
COUNT(*) AS TotalConnections,
SUM(CASE WHEN status = ‘running’ THEN 1 ELSE 0 END) AS ActiveConnections,
SUM(CASE WHEN status = ‘sleeping’ THEN 1 ELSE 0 END) AS SleepingConnections,
SUM(CASE WHEN DATEDIFF(MINUTE, last_request_end_time, GETDATE()) > 30
THEN 1 ELSE 0 END) AS LongIdleConnections
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
GROUP BY DB_NAME(database_id);
END;
GO

Command(s) completed successfully.

— 执行监控
EXEC sp_fgedu_monitor_connections;
GO

CheckTime DatabaseName TotalConnections ActiveConnections SleepingConnections LongIdleConnections
———————– ———— —————- —————– ——————- ——————-
2026-04-08 14:00:00 fgedudb 185 12 173 45
2026-04-08 14:00:00 master 8 2 6 0

生产环境建议:建立完善的连接池监控体系,定期检查连接使用情况,及时清理长时间空闲连接,优化应用代码确保连接正确释放。from SQLServer视频:www.itpux.com

Part05-风哥经验总结与分享

5.1 SQLServer数据库连接池最佳实践

SQLServer数据库连接池最佳实践:

  • 合理配置连接池大小:根据业务并发量配置最小和最大连接数
  • 设置连接超时:避免长时间等待连接导致请求超时
  • 启用连接重置:确保从池中获取的连接状态干净
  • 设置连接生命周期:定期回收长时间使用的连接
  • 监控连接使用:建立监控体系及时发现连接问题
  • 代码规范:确保所有连接正确关闭和释放

5.2 SQLServer数据库连接池检查清单

# SQLServer数据库连接池检查清单

1. 服务器端配置检查
[ ] user connections配置是否合理
[ ] max worker threads配置是否合理
[ ] 内存配置是否充足
[ ] CPU资源是否充足

2. 应用端配置检查
[ ] 连接池大小配置是否合理
[ ] 连接超时配置是否合理
[ ] 连接生命周期配置是否合理
[ ] 连接重置是否启用

3. 监控检查
[ ] 是否有连接池监控
[ ] 是否有连接告警
[ ] 是否定期检查连接状态
[ ] 是否有连接泄漏检测

4. 代码检查
[ ] 是否正确关闭连接
[ ] 是否使用using语句
[ ] 是否有异常处理
[ ] 是否有连接泄漏风险

5. 性能检查
[ ] 连接获取时间是否正常
[ ] 连接等待是否频繁
[ ] 连接池是否经常满
[ ] 是否有空闲连接过多

5.3 SQLServer数据库连接池管理工具推荐

SQLServer数据库连接池管理工具推荐:

  • SQL Server Management Studio:查看连接状态和会话信息
  • 动态管理视图:sys.dm_exec_sessions、sys.dm_exec_connections
  • 性能计数器:监控连接池性能指标
  • 应用程序监控:APM工具监控连接池使用情况
  • 自定义脚本:定期检查和清理连接
风哥提示:连接池优化是一个持续的过程,需要根据业务发展和系统负载不断调整。建议建立完善的监控体系,定期分析连接池使用情况,及时发现和解决问题。更多视频教程www.fgedu.net.cn

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息