如何确定MS SQL Server 2005中打开/活动连接的总数

110

我的 PHP/MS Sql Server 2005/win 2003 应用程序偶尔会变得非常无响应,但内存/CPU 使用率不会飙升。如果我尝试从 SQL Management Studio 打开任何新连接,它只会停留在打开连接对话框上。如何确定 MS Sql Server 2005 中活动连接的总数。

8个回答

302

这显示了每个数据库的连接数:

SELECT 
    DB_NAME(dbid) as DBName, 
    COUNT(dbid) as NumberOfConnections,
    loginame as LoginName
FROM
    sys.sysprocesses
WHERE 
    dbid > 0
GROUP BY 
    dbid, loginame

所有数值相加的和为:

SELECT 
    COUNT(dbid) as TotalConnections
FROM
    sys.sysprocesses
WHERE 
    dbid > 0

如果您需要更详细的信息,请运行:

sp_who2 'Active'

注意: 使用的 SQL Server 账户需要具有 "sysadmin" 角色 (否则结果将仅显示单行和计数为1)


2
非常感谢,太棒了。对于像我这样的新手,启动SQL Server Management Studio后,右键单击您的数据库,选择“新建查询”,将此粘贴并点击“!Go”按钮即可。 - user1902431
10
这个回答不正确,不应接受也不应被选为最佳答案。只有当你以 sa 用户身份登录时才能依赖返回的数字。如果你以非 sa 用户身份登录,则会看到 1,这并不能代表实际连接数。请注意,这里不提供解释。 - ajeh
5
你需要具备足够的权限来执行任务,这是隐含的。你的评论是多余的。 - Mitch Wheat
1
@MitchWheat 建议在你的回答中加注释说明,为了获取SQL Server的实际/全部连接,运行此脚本所使用的帐户需要具有“sysadmin”权限。 - IEBasara
2
@IEBasara:这是隐式的。你为什么会期望非管理员能够查看这样的信息呢? - Mitch Wheat
1
晚来了一步,但是sysadmin角色所需的(编辑注释)拯救了我的后半生。我一直得到1,假设我有正确的权限。终于解决了!胜利 :money_with_wings: - Pure.Krome

8
使用此功能可以准确计算每个连接池的数量(假设每个用户/主机进程使用相同的连接字符串)。
SELECT 
DB_NAME(dbid) as DBName, 
COUNT(dbid) as NumberOfConnections,
loginame as LoginName, hostname, hostprocess
FROM
sys.sysprocesses with (nolock)
WHERE 
dbid > 0
GROUP BY 
dbid, loginame, hostname, hostprocess

7

正如 @jwalkerjr 提到的,如果启用了连接池,则应在代码中处理连接(它们只会被返回到连接池)。建议的做法是使用 'using' 语句:

// Execute stored proc to read data from repository
using (SqlConnection conn = new SqlConnection(this.connectionString))
{
    using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "LoadFromRepository";
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@ID", fileID);

        conn.Open();
        using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            if (rdr.Read())
            {
                filename = SaveToFileSystem(rdr, folderfilepath);
            }
        }
    }
}

提问者提到他们正在使用PHP,因此代码示例可能不适合他们。当没有更多引用它们时(并且所有引用将在页面周期结束时被删除),垃圾收集器应自动清理非持久性SQL Server连接,但也许提问者正在使用持久性连接,这需要智能连接重用。 - Paul d'Aoust

5

我知道这篇文章有点老了,但是我认为更新一下还是很有必要的。如果需要准确计算,那么ECID列也应该被过滤。具有并行线程的SPID可能会在sysprocesses中出现多次,过滤ECID=0将返回每个SPID的主线程。

SELECT 
    DB_NAME(dbid) as DBName, 
    COUNT(dbid) as NumberOfConnections,
    loginame as LoginName
FROM
    sys.sysprocesses with (nolock)
WHERE 
    dbid > 0
    and ecid=0
GROUP BY 
    dbid, loginame

1

0

基于MS SQL知识 - 如何知道哪些主机打开了SQL数据库连接并占用了它们。

使用以下查询,您将找到数据库列表、主机名和打开连接计数的总数,根据这些信息,您将了解哪个主机占用了SQL连接。

SELECT DB_NAME(dbid) as DBName, hostname ,COUNT(dbid) as NumberOfConnections
FROM sys.sysprocesses with (nolock) 
WHERE dbid > 0 
and len(hostname) > 0 
--and DB_NAME(dbid)='master' /* Open this line to filter Database by Name */
Group by DB_NAME(dbid),hostname
order by DBName

0

看一下sp_who,它会给你比仅仅查看连接数更多的细节。

在你的情况下,我会这样做:

 DECLARE @temp TABLE(spid int , ecid int, status varchar(50),
                     loginname varchar(50),   
                     hostname varchar(50),
blk varchar(50), dbname varchar(50), cmd varchar(50), request_id int) 
INSERT INTO @temp  

EXEC sp_who

SELECT COUNT(*) FROM @temp WHERE dbname = 'DB NAME'

0
SELECT
[DATABASE] = DB_NAME(DBID), 
OPNEDCONNECTIONS =COUNT(DBID),
[USER] =LOGINAME
FROM SYS.SYSPROCESSES
GROUP BY DBID, LOGINAME
ORDER BY DB_NAME(DBID), LOGINAME

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接