我需要將包含特定命名錶的服務器的附加數據庫列表填充到兩個下拉框中。我目前的方法是這樣的。獲取包含表的數據庫列表的有效方法
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我只打開兩個連接並重新使用它們,如果表存在,則花費在查詢上的時間。 –