必须更改SQL脚本以减少SQL Serverload

时间:2015-07-28 13:02:09

标签: c# sql-server-2008

几年前,它是一个旨在将人员导入临时表的脚本。现在这个脚本加载需要10分钟,有时会导致问题。

所以我决定检查代码进行优化,但我不知道如何更改它。

当前代码如下所示

// Getting attributes from the configfile
string filePath = getAppSetting("filepath");
string fileName = getAppSetting("filename");
string fileBP = filePath + fileName;

if (File.Exists(fileBP))
{
    // Truncate Temp-Table
    SqlCommand command = new SqlCommand("TRUNCATE TABLE [dbo].[temp_person];", connection);
    command.ExecuteNonQuery();
FileStream logFileStream = new FileStream(fileName, FileMode.Open,     FileAccess.Read, FileShare.ReadWrite);
StreamReader logFileReader = new StreamReader(logFileStream, System.Text.Encoding.Default);

while (!logFileReader.EndOfStream)
{
    string line = logFileReader.ReadLine();
    strActLine = line;
    string sql = "INSERT INTO temp_person(per_nummer, per_pid, per_name)"
                 + "VALUES(@per_nummer, @per_pid, @per_name)"

    SqlCommand cmd = new SqlCommand(sql, connection);

    cmd.Parameters.AddWithValue("@per_nummer", isNull(line.Substring(0, 7)));
    cmd.Parameters.AddWithValue("@per_pid", isNull(line.Substring(7, 7)));
    cmd.Parameters.AddWithValue("@per_name", isNull((line.Substring(14, 20))));
    cmd.ExecuteNonQuery();
}
// Clean up
connection.Close();
logFileReader.Close();
    logFileStream.Close();
}

在这段代码中,我为每个人打开了一个新连接,这样做是没有意义的。是否有可能将其更改为批量插入或类似的东西?该文件没有任何类型的分隔符,如";"

我正在使用 MSSQL 2008 R2, .Net 4.0(此服务器上目前无法使用更高版本)

3 个答案:

答案 0 :(得分:1)

假设您的logFileStream文件(“fileName”)包含您正在加载的所有用户,您不会按照您的想法打开新连接。它当前使用一个连接来TRUNCATE表,然后从文件fileName加载所有条目。

使此运行更快的唯一方法是使用批量插入SQL Server语句,您可以在此处找到详细信息:https://msdn.microsoft.com/en-us/library/ms188365.aspx

答案 1 :(得分:1)

您是否调查过SqlBulkCopy课程?它提供了几种不同的方法将数据从.NET代码批量复制到SQL Server。以下是使用DataTable缓冲记录的示例:

if (File.Exists(fileName))
{
    TruncateTempTable(connection);
    DataTable newRecs = new DataTable();
    newRecs.Columns.Add("per_nummer", typeof (string));
    newRecs.Columns.Add("per_pid", typeof(string));
    newRecs.Columns.Add("per_name", typeof(string));
    using (TextReader tr = File.OpenText(fileName))
    {
        while (tr.Peek() > 0)
        {
            string theLine = tr.ReadLine();
            DataRow newRow = newRecs.NewRow();
            newRow["per_nummer"] = theLine.Substring(0, 7);
            newRow["per_pid"] = theLine.Substring(7, 7);
            newRow["per_name"] = theLine.Substring(14, 20);
            newRecs.Rows.Add(newRow);
        }
    }
    SqlBulkCopy bulkCopy = new SqlBulkCopy(connection);
    bulkCopy.WriteToServer(newRecs);
}

上面的MSDN链接提供了更多细节。

答案 2 :(得分:0)

我希望这会起作用

BULK INSERT Reports FROM  @ReportFile WITH (FIELDTERMINATOR = '|',ROWTERMINATOR = '\n') 

如果文件数据如

M1009|20130502|E400969|ARACIL ALONDRA A|2013050220131202201404022014040220140408
M1009|20130502|N1000533|BARRY PATRICIA| 2013050220131202201404022014040220140408
M1009|20130502|N1001263|GRAYSON JOSEPH| 2013050220131202201404022014040220140408
M1009|20130502|N1026710|GANZI LOUIS R.| 2013050220131202201404022014040220140408

这适用于t-sql