我需要将包含特定命名表的服务器的附加数据库列表填充到两个下拉框中。我目前的方法是这样的。获取包含表的数据库列表的有效方法
List<string> dbType1 = new List<string>();
List<string> dbType2 = new List<string>();
using (var conn = new SqlConnection("Data Source=(local);Integrated Security=true"))
using (var cmd = new SqlCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select name from sys.databases";
using (var innerConn = new SqlConnection("Data Source=(local);Integrated Security=true"))
using (var innerCmd = new SqlCommand())
using (var rdr = cmd.ExecuteReader())
{
innerConn.Open();
innerCmd.Connection = innerConn;
while (rdr.Read())
{
string table = rdr.GetString(0);
innerCmd.CommandText = String.Format("select name from [{0}]..sys.tables where name in 'EF_LAB_FIELDS_DYNA' 'AUTOXPAY_PAYMENTS'", table);
object result = innerCmd.ExecuteScalar();
if(result != null)
{
if ((string)result == "EF_LAB_FIELDS_DYNA")
dbType1.Add(table);
else
dbType2.Add(table);
}
}
}
}
cb.Items.AddRange(dbType1.ToArray());
cb2.Items.AddRange(dbType2.ToArray());
这可以工作,但是在具有205个附加数据库的服务器上运行需要44.6秒。
任何人都可以给我任何关于如何加快此操作的建议吗?我愿意使用SMO等其他技术,进行更多的客户端处理,或者将其作为服务器上某种形式的复杂查询运行。只要我根据两个表名得到两个列表,它就能满足我的需求。
下面是更新后的版本,使我的运行时间降到了第二位,这要归功于总的建议。
ConcurrentBag<string> dbType1 = new ConcurrentBag<string>();
ConcurrentBag<string> dbType2 = new ConcurrentBag<string>();
List<string> databases = new List<string>();
using (var conn = new SqlConnection("Data Source=(local);Integrated Security=true"))
using (var cmd = new SqlCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select name from sys.databases";
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
databases.Add(rdr.GetString(0));
}
Parallel.ForEach(databases,() =>
{
var innerConn = new SqlConnection("Data Source=(local);Integrated Security=true");
var innerCmd = new SqlCommand("", innerConn);
innerConn.Open();
return innerCmd;
},
(database, loopState, localCommand) =>
{
localCommand.CommandText = String.Format("select name from [{0}].sys.tables where name in ('EF_LAB_FIELDS_DYNA', 'AUTOXPAY_PAYMENTS')", database);
object result = localCommand.ExecuteScalar();
if (result != null)
{
if ((string)result == "EF_LAB_FIELDS_DYNA")
dbType1.Add(database);
else
dbType2.Add(database);
}
return localCommand;
},
(localCommand) =>
{
var temp = localCommand.Connection;
localCommand.Dispose();
temp.Dispose();
});
}
}
你有什么可以分析,看看时间正在接受?我的猜测主要是打开你可能无法避免的连接。 – pstanton
@pstanton我只打开两个连接并重新使用它们,如果表存在,则花费在查询上的时间。 –