C# 要在每个数据库上运行查询,如何计算C和SQL Server中的性能差异
我正在开发sql server监控产品,我有一个数据库查询,它将获取有关sql server中所有数据库的所有表详细信息的数据 为此,我有两个选择 从[master].sys.sysdatabases中选择名称从代码启动数据库查询 首先获取所有数据库的数据库名,然后我将对每个数据库进行主查询 使用+主查询 请检查以下代码以获取相同信息C# 要在每个数据库上运行查询,如何计算C和SQL Server中的性能差异,c#,.net,sql-server-2008,C#,.net,Sql Server 2008,我正在开发sql server监控产品,我有一个数据库查询,它将获取有关sql server中所有数据库的所有表详细信息的数据 为此,我有两个选择 从[master].sys.sysdatabases中选择名称从代码启动数据库查询 首先获取所有数据库的数据库名,然后我将对每个数据库进行主查询 使用+主查询 请检查以下代码以获取相同信息 public DataTable GetResultsOfAllDB(string query) { SqlConnection con = new Sq
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;
}
我将使用sys存储过程,即EXEC sp_MSforeachdb,获取的数据将存储在表datatype select from tentable中的存储数据中;这张桌子很诱人。
检查以下查询以获得相同的结果
声明@TableDetail表
现场1 varchar500,
字段2 int,
第3场varchar500,
字段4 varchar500,
字段5小数点18,2,
字段6小数点18,2
插入@TableDetail EXEC sp_MSforeachdb'USE[?];QYERY/用于所有数据库的命令'
选择
来自@TableDetail的字段1、字段2、字段3、字段4、字段5、字段6
注意:在第二个选项中,查询需要时间,因为若数据库和表的数量很大,那个么这将等待所有数据库完成
现在我的问题是,从以上两个选项中,哪一个是好的选项?为什么?或任何其他解决方案
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;
}
提前感谢。一个关键区别是第二个选项会一直阻塞,直到所有操作都完成。所有的工作都是在sql server端完成的。这有一个问题,即在用户运行时无法将反馈应用于用户,并且可能会超时,并且无法适应网络漏洞。这个选项可以作为纯sql脚本使用,一些sql管理员,比如第一个需要程序的地方 在第一个示例中,客户机正在执行迭代的更细粒度的任务,您可以在其中向用户提供反馈。您还可以在遇到网络漏洞时重试,而无需重新执行所有工作。在第一个示例中,您还可以使用SqlConnectionBuild而不是Concatation
如果性能是一个问题,您还可以在适配器周围使用一些锁定来并行第一个适配器。Fill两者都很糟糕-它们都是串行的 使用第一种方法,摆脱荒谬的对象数据集,同时使用任务并行化X数据库。通过尝试ut确定服务器可以处理多少负载
已完成。如果查询足够简单,您可以尝试生成单个脚本,而不是逐个在每个数据库中执行查询:
select 'DB1' as DB, Field1, Field2, ...
from [DB1]..[TableOrViewName]
union all
select 'DB2' as DB, Field1, Field2, ...
from [DB2]..[TableOrViewName]
union all
...
一切看起来都很好。我只想为IDisposable对象添加Using语句
您将如何确定每个测试之间的系统和网络延迟差异,这最终可能是与数据库性能无关的定义因素。我关心的是,每次打开每个数据库的连接并获取数据,还是只打开一个连接就可以运行大型查询。关于N/W延迟,是的,你是对的,这与DB性能无关,但对于每个DB或oly one连接器,哪一个重新打开连接更好?你在这里做了什么?是的,你是对的,但问题是我的应用程序在2.0中很难处理2.0中的并行性。我必须应用线程,然后我不想这样做,因为这个产品是监控产品,我不想做这样的事情。。谢谢你的回复。啊-不,对不起。使用线程池,将用户工作项排队。我从1.0开始就一直在做这些事情。没问题。