想要在每个数据库上运行查询,如何计算C#和SQL Server中的性能差异
本文关键字:SQL 计算 Server 性能 数据库 运行 何计算 查询 | 更新日期: 2023-09-27 18:21:31
我正在开发sql server监控产品,我有一个数据库查询,它将获取有关sql server中所有数据库的所有表详细信息的数据。
对此,我有两种选择。
-
以
select name from [master].sys.sysdatabases
的形式从代码中激发数据库查询首先获取所有数据库的数据库名称,然后我将在每个数据库上启动主查询使用"USE <fetched DB name>;"+"mainQuery";
请检查以下代码是否相同。
public DataTable GetResultsOfAllDB(string query) { SqlConnection con = new SqlConnection(_ConnectionString); string locleQuery = "select name from [master].sys.sysdatabases"; DataTable dtResult = new DataTable("Result"); SqlCommand cmdData = new SqlCommand(locleQuery, con); cmdData.CommandTimeout = 0; SqlDataAdapter adapter = new SqlDataAdapter(cmdData); DataTable dtDataBases = new DataTable("DataBase"); adapter.Fill(dtDataBases); foreach (DataRow drDB in dtDataBases.Rows) { if (dtResult.Rows.Count >= 15000) break; locleQuery = " Use [" + Convert.ToString(drDB[0]) + "]; " + query; cmdData = new SqlCommand(locleQuery, con); adapter = new SqlDataAdapter(cmdData); DataTable dtTemp = new DataTable(); adapter.Fill(dtTemp); dtResult.Merge(dtTemp); } return dtResult; }
-
我将使用系统存储过程,即EXEC sp_MSforeachdb,提取的数据将存储在从临时表中选择的表数据类型中;删除表临时表。检查相同的以下查询
Declare @TableDetail table ( field1 varchar(500), field2 int, field3 varchar(500), field4 varchar(500), field5 decimal(18,2), field6 decimal(18,2) ) INSERT @TableDetail EXEC sp_MSforeachdb 'USE [?]; QYERY/COMMAND FOR ALL DATABASE' Select field1,field2 ,field3 ,field4 ,field5,field6 FROM @TableDetail
注意:在第二个选项中,查询需要时间,因为如果数据库的数量和表的数量很大,那么这将等待所有数据库完成。
现在我的问题是,从以上两个选项中,哪一个是好的选项,为什么?或其任何其他解决方案。
提前谢谢。
一个关键区别是第二个选项块,直到一切完成。所有的工作都是在sql服务器端完成的。这就带来了无法在运行时向用户应用反馈的问题,而且它可能会超时,无法适应网络突发事件。这个选项可以用作纯sql脚本(有些sql管理员喜欢这样),其中第一个需要程序。
在第一个示例中,客户端正在执行更精细的迭代任务,您可以在其中向用户提供反馈。你也可以在面对网络故障时重试,而无需重做所有工作。在第一个示例中,您还可以使用SqlConnectionBuild而不是use连接。
如果性能是一个问题,您还可以通过一些锁定适配器来并行化第一个问题。填充
两者都很糟糕-它们都是串行的。
使用第一个,去掉荒谬的对象(DataSet),同时使用TASKS并行化X数据库。X通过尝试服务器可以处理多少负载来确定。
完成。
如果查询足够简单,您可以尝试生成单个脚本,而不是在每个DB中逐个执行查询:
select 'DB1' as DB, Field1, Field2, ...
from [DB1]..[TableOrViewName]
union all
select 'DB2' as DB, Field1, Field2, ...
from [DB2]..[TableOrViewName]
union all
...
一切看起来都很好。我只想为IDisposable对象添加Using语句
public DataTable GetResultsOfAllDB(string query)
{
using (SqlConnection con = new SqlConnection(_ConnectionString))
{
string locleQuery = "select name from [master].sys.sysdatabases";
DataTable dtResult = new DataTable("Result");
using (SqlCommand cmdData = new SqlCommand(locleQuery, con))
{
cmdData.CommandTimeout = 0;
using (SqlDataAdapter adapter = new SqlDataAdapter(cmdData))
{
using (DataTable dtDataBases = new DataTable("DataBase"))
{
adapter.Fill(dtDataBases);
foreach (DataRow drDB in dtDataBases.Rows)
{
if (dtResult.Rows.Count >= 15000)
break;
locleQuery = " Use [" + Convert.ToString(drDB[0]) + "]; " + query;
cmdData = new SqlCommand(locleQuery, con);
adapter = new SqlDataAdapter(cmdData);
using (DataTable dtTemp = new DataTable())
{
adapter.Fill(dtTemp);
dtResult.Merge(dtTemp);
}
}
return dtResult;
}
}
}
}
}