C# 要在每个数据库上运行查询,如何计算C和SQL Server中的性能差异

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

我正在开发sql server监控产品,我有一个数据库查询,它将获取有关sql server中所有数据库的所有表详细信息的数据

为此,我有两个选择

从[master].sys.sysdatabases中选择名称从代码启动数据库查询 首先获取所有数据库的数据库名,然后我将对每个数据库进行主查询 使用+主查询

请检查以下代码以获取相同信息

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开始就一直在做这些事情。没问题。