SqlDataAdapter.Fill 命令使 SQL CPU 达到峰值

Posted

技术标签:

【中文标题】SqlDataAdapter.Fill 命令使 SQL CPU 达到峰值【英文标题】:SQL CPU peaks with SqlDataAdapter.Fill Command 【发布时间】:2012-09-04 16:32:28 【问题描述】:

我注意到一些将 SQL 数据导入 c# 应用程序的特殊行为。我使用了数据集 xsd,但这开始超时。然后我改变了我的方法,因为我已经有一个类可以为我尝试过的其他操作生成并返回一个数据表。这也超时了。

我在 SSMS 中打开了活动监视器,以了解代码运行时 SQL 中发生了什么,并注意到无论我以何种方式运行它,填充命令都会导致 SQL Sever 在 100% CPU 达到峰值并停留在那里直到命令被取消。这是一台具有大量 240Ghz 处理器和 30GB RAM 的优质服务器。该查询不完全是 zippy,但在 SSMS 中在 3 秒内返回 100k 行。

这是我的数据集代码:

        public DataTable UKDataRefresh ()
    
        UKREFRESH.UKNewContactsDataTable dt = 
            new UKREFRESH.UKNewContactsDataTable();
        UKREFRESHTableAdapters.UKNewContactsTableAdapter ta = 
            new UKREFRESHTableAdapters.UKNewContactsTableAdapter();

        ta.Connection.ConnectionString += ";Password = xxxxxx;";

        try
        
        ta.Fill(dt, global::SilverPopTransfer.Properties.Settings.Default.UKDATELASTACTION);

        
        catch (SqlException )
        

            throw;
        

        return dt;

    

这是我即时构建它的代码:

public DataTableOperations (string strconnection, string strSelect,string tablename)

        SqlConnection c = new SqlConnection(strconnection);
        connection = c;
        SqlDataAdapter da = new SqlDataAdapter(strSelect, connection);
        DataSet ds = new DataSet();
        //added this to see what would happen.
        da.SelectCommand.CommandTimeout = 0;
        connection.Open();
        da.Fill(ds, tablename);
        connection.Close();
        Datatable = ds.Tables[tablename];
        _disposed = false;
    

我正在寻找可能导致问题的线索,而不是完整的解决方案。 顺便说一句,我在发布之前在预先存在的控制台应用程序中运行了一个类似的功能,它连接并运行没有错误:查询几乎相同。

唯一的区别是,对于预先存在的应用程序,我使用集成安全性,但在这种情况下,我指定了用户和密码。我确认登录凭据。

【问题讨论】:

【参考方案1】:

在执行前检查索引和set nocount on。 SSMS 性能并不是一个好的性能指标。它只获取部分数据并异步执行。尝试调用一小部分数据或运行查询而不填满表格。这可能是瓶颈。

如果您正在运行带参数的选择,sql server 将使用sp_execute 执行它,然后服务器编译它创建 CPE 峰值。

【讨论】:

谢谢我查看了代码并尝试了您的建议:SqlCommand cmnd = new SqlCommand(strSelect, connection); CommandBehavior behave = CommandBehavior.Default; connection.Open(); IAsyncResult result = cmnd.BeginExecuteReader(behave); using (SqlDataReader reader = cmnd.EndExecuteReader(result)) DisplayResults(reader); 这与以前的结果相同。即 CPU 中的大量峰值和 很多 进程触发。

以上是关于SqlDataAdapter.Fill 命令使 SQL CPU 达到峰值的主要内容,如果未能解决你的问题,请参考以下文章

SqlDataAdapter.Fill(DataGridView.DataSource) 复制所有行

SqlDataAdapter.Fill 方法不会给出任何错误,但也不会返回任何数据以用于长时间运行的查询 ado.net core SQL Server

SqlDataAdapter.Fill - 异步方法

SqlDataAdapter.Fill() 溢出异常

SqlClient.SqlDataAdapter.Fill(DataSet) 结果如果不选择查询

SqlDataAdapter.Fill 方法慢