SQL服务器速度减慢,可能是什么原因/改进方法?

时间:2012-05-02 11:23:55

标签: sql sql-server sql-server-2008

我有一组30个文件。我遍历这些文件,每插入1529行,其中包含大约30列,219487行包含大约6列。

我在C#中这样做,我通过数据表插入(见底部)。对于1529行(30列),我已将插入分组为每批1,300行,对于219,487行(6列),我将每批50000行分组。

插入每个批处理时,没有多线程 - 一切都是顺序的(至少在我的代码中)。在我的代码行完成插入上一个文件之前,我不会从下一个文件开始。

考虑到这一点,我希望SQL服务器在一个固定的时间内完成每个文件(文件非常相似,总是1529和219487插入)。

但是,每个文件每次插入SQL所需的时间会线性增加 - 从第一个文件的9秒到第30个文件的50秒。我已经将CPU时间与SQL时间分开,并且在开始时花费0.000033秒来插入6列行中的一行。接下来,对于后面的文件,对于6列数据,所花费的时间是0.000228。换句话说,插入219,487行(6列)数据所需的时间增加了约7倍?

我将批量大小减少到20000,并没有任何区别。在过去,我相信我将它减少到5000和10000,它仍然没有任何区别。我对基础SQL架构知之甚少,所以我有点迷失。

我觉得我正在重载SQL服务器。但是,是否有人认为这是按顺序完成的,而不是给SQL服务器提供工作?它可能是通过线程产生的SQL请求,但是我将批量大小减少到100(见下文),这仍然没有帮助。完成的总时间较长,但每个文件仍然呈线性增长。

我已将批量大小减少到100(只是为了确保服务器没有过载)并且我仍然看到线性增加的时间?

我一直指的是SQL插入所用的时间,而不是每个文件的SQL + CPU时间组合。

可能无法确切地告知发生了什么,但我是否可以提供一些提示和事情以避免最好地解决这个问题?

我的SQL插入代码(每次批量插入调用)是:

private static void WriteResultsToDatabase(string tableName, DataTable tableToWrite)
        {

            using (SqlConnection connection =
                    new SqlConnection(connectionString))
            {
                SqlBulkCopy bulkCopy =
                    new SqlBulkCopy
                    (
                    connection,
                    SqlBulkCopyOptions.TableLock |
                    SqlBulkCopyOptions.FireTriggers |
                    SqlBulkCopyOptions.UseInternalTransaction,
                    null
                    );

                bulkCopy.DestinationTableName = tableName;
                for (int i = 0; i < tableToWrite.Columns.Count; i++)
                    bulkCopy.ColumnMappings.Add(tableToWrite.Columns[i].ColumnName, tableToWrite.Columns[i].ColumnName);
                try
                {
                    connection.Open();

                    bulkCopy.WriteToServer(tableToWrite);

                }
                finally
                {
                    connection.Close();
                }
            }
        }

2 个答案:

答案 0 :(得分:0)

  

我觉得我正在重载SQL服务器

是的,这是一个很好的理由 - 特别是只有当你的sql server在手机上运行或者有一个可怜的最终用户光盘时。否则 - 不。

  

我对基础SQL架构知之甚少,所以我有点迷失。

找出答案。获取查询计划。需要表+指数。独特的约束?是否有一个唯一的约束没有索引?这会一直强制进行表格扫描。

另外值得:插入您从原始表创建的临时表(平凡),然后在一个语句中复制数据。

  

从第一个文件的9秒开始

对于已经足够的220,000行。我建议检查服务器在你的poerations中有多忙,以及在表上匹配索引的所有约束。和触发器;)

答案 1 :(得分:0)

这可能是任何数量的事情,但对我来说显而易见的事情如下:

  1. 表上有一个聚簇键,而您没有插入 记录按该键的顺序排列。对于每个插入操作, 它需要在完成记录之前对记录进行物理重新排序 任务。
  2. 你有多个索引/外键,检查表, 因此,每次迭代都会添加越来越多的信息 检查。
  3. 您的触发器未被有效使用或未构建 有效地,它需要与整个工作相对应 表而不是最近插入的数据。
  4. 您已经设置了批量交易,但有些事情阻止了 数据库服务器就像对待它一样。确保活动 monitor将此视为批量操作。
  5. 您是按百分比而不是按百分比自动增长数据库 定额,固定金额;对于每次成长,分配更多时间需要更长时间 空间。
  6. 这些都是我以前遇到的所有问题;他们中的任何一个或任何组合都可能产生你所描述的症状。