我有十几台服务器。
每个服务器都有一个IIS,其网站执行以下大型SQL脚本每5分钟。
在某些服务器上,承载网站的池崩溃。该池仅包含此站点。
我需要在每次撞车后回收游泳池......目前用我的双手。
因此,网站存在问题,我认为是使用大型SQL脚本。
string root = AppDomain.CurrentDomain.BaseDirectory;
string script = File.ReadAllText(root + @"..\SGBD\select_user_from_all_bases.sql").Replace("$date", dtLastModif);
string connectionString = @"Data Source=(local);Integrated Security=SSPI";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var command = new SqlCommand(script, connection);
var reader = command.ExecuteReader();
var users = new List<UserModel>();
while (reader.Read())
{
users.Add(new UserModel()
{
dbName = String.Format("{0}", reader[0]),
idExternal = int.Parse(String.Format("{0}", reader[1])),
firstname = String.Format("{0}", reader[2]),
lastname = String.Format("{0}", reader[3]),
login = String.Format("{0}", reader[4]),
password = String.Format("{0}", reader[5]),
dtContractStart = reader[6] != DBNull.Value ? (DateTime?)reader[6] : null,
dtContractEnd = reader[7] != DBNull.Value ? (DateTime?)reader[7] : null,
emailPro = String.Format("{0}", reader[8]),
emailPerso = String.Format("{0}", reader[9])
});
}
return users;
}
USE master
DECLARE db_names CURSOR FOR
SELECT name FROM sysdatabases WHERE [name] LIKE 'FOO_%' AND [name] NOT LIKE 'FOO_TRAINING_%'
DECLARE @db_name NVARCHAR(100)
DECLARE @query NVARCHAR(MAX)
DECLARE @queryFinal NVARCHAR(MAX)
SET @query = ''
OPEN db_names
FETCH NEXT FROM db_names INTO @db_name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @query = @query + 'SELECT ''' + @db_name + ''', id_salarie, nom, prenom, login COLLATE SQL_Latin1_General_CP1_CI_AS, password COLLATE SQL_Latin1_General_CP1_CI_AS, date_arrivee, date_depart, email COLLATE SQL_Latin1_General_CP1_CI_AS, persoMail COLLATE SQL_Latin1_General_CP1_CI_AS FROM [' + @db_name + '].dbo.utilisateurs WHERE dt_last_modif >= ''$date'' UNION '
FETCH NEXT FROM db_names INTO @db_name
END
DEALLOCATE db_names
SET @queryFinal = left(@query, len(@query)-6)
EXEC sp_executesql @queryFinal
答案 0 :(得分:1)
您是否尝试过在使用后读取器被隐藏起来?
using(var reader = command.ExecuteReader()) { ...
如果关闭连接
,我不是舒尔 using (var connection = new SqlConnection(connectionString))
负责命令和读者资源。
答案 1 :(得分:1)
我会在这里做一些事情......如果你的问题是那么持久。首先,我不会生成一个完整的SQL查询,试图一次性从所有这些表中获取数据。接下来,查询正在查询,并暗示可能正在尝试锁定与查询相关联的记录以进行可能的更新...即使您可能不会这样做。
我会在from表中添加WITH (NOLOCK)
。
select columns from yourTable WITH(NOLOCK) where...
这可以防止锁定与查询关联的所有页面的任何开销。
现在,如何更好地处理循环。在你的fetch循环之前,我会立即创建一个预期输出结果的临时表...类似于
(不确定您的结构的列名长度......
create #C_TempResults
( fromDBName char(20),
id_salarie int,
nom char(10),
prenom char(10),
login char(10),
password char(10),
date_arivee datetime,
date_depart datetime,
email char(60),
persoMail char(60) );
然后,在你已循环遍历所有正在查询的表的循环中,而不是构建一个连续的SQL语句以在最后执行,只需运行一个时间,并插入临时表,如..
(same beginning to prepare your fetch cursor...)
BEGIN
SET @query = 'INSERT INTO #C_TempResults '
+ ' SELECT ''' + @db_name + ''' as fromDBName, id_salarie, nom, prenom, '
+ 'login COLLATE SQL_Latin1_General_CP1_CI_AS, '
+ 'password COLLATE SQL_Latin1_General_CP1_CI_AS, '
+ 'date_arrivee, date_depart, '
+ 'email COLLATE SQL_Latin1_General_CP1_CI_AS, '
+ 'persoMail COLLATE SQL_Latin1_General_CP1_CI_AS '
+ 'FROM [' + @db_name + '].dbo.utilisateurs WITH (NOLOCK) '
+ 'WHERE dt_last_modif >= ''$date'' ';
-- Run this single query now, get the data and release any "lock" resources
EXEC sp_executesql @queryFinal
-- now, get the next database to query from and continue
FETCH NEXT FROM db_names INTO @db_name
END
DEALLOCATE db_names
-- FINALLY, just run your select from the temp table that has everything all together...
select * from #C_TempResults;
-- and get rid of your "temp" table
drop table #C_TempResults;