我可以提高执行报表的速度吗?

时间:2014-06-04 15:28:34

标签: sql-server performance visual-studio-2010 sql-update

我的功能:删除给定表格

的特定行中的单位
private static void removeUnits(String connectionString, String tableName, String columnID, String columnToFix)
{
    List<String> rowsToEdit = new List<String>();

    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
            connection.Open();
            using (var reader = command.ExecuteReader())
            {

                var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
                var indexOfT_VALUE = reader.GetOrdinal(columnToFix);
                while (reader.Read())
                {
                    var t_value = reader.GetValue(indexOfT_VALUE);
                    var t_id = reader.GetValue(indexOfR_MEASUREDVALUEID);

                    String newValue = getWithoutUnit(t_value.ToString());
                    if (newValue != null)
                    {
                        String sql = "UPDATE " + tableName + " SET " + columnToFix + "='" +
                            newValue + "' WHERE " + columnID + "='" + t_id + "';";
                        rowsToEdit.Add(sql);
                    }
                }
                connection.Close();
            }
        }

        Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
        Console.ReadLine();

        SqlCommand sqlCmd;
        sqlCmd = new SqlCommand("", connection);
        sqlCmd.Connection.Open();

        foreach (String command in rowsToEdit)
        {
            sqlCmd.CommandText = command;
            sqlCmd.ExecuteNonQuery();
        }
    }
    Console.WriteLine(rowsToEdit.Count + " commands executed");
}

我在Visual Studio 2010和SQL-Server 2012中使用C#。 它工作正常,但执行200000行需要很长时间。 是否可以更快地完成这项工作?

2 个答案:

答案 0 :(得分:1)

我的建议涉及调查并行性:

注意:代码未经过测试,只需在Notepad ++中输入

即可
private static void removeUnits(String connectionString, String tableName, String  columnID, String columnToFix)
{
List<new Tuple<object, object>> rowsToEdit = new List<new Tuple<object, object>>();

using (SqlConnection connection = new SqlConnection(connectionString))
{
    using (var command = connection.CreateCommand())
    {
        command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
        connection.Open();
        using (var reader = command.ExecuteReader())
        {
            var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
            var indexOfT_VALUE = reader.GetOrdinal(columnToFix);

            while (reader.Read())
            {
                rowsToEdit.Add(new Tuple<object, object>(reader.GetValue(indexOfT_VALUE),reader.GetValue(indexOfR_MEASUREDVALUEID)));
            }
            connection.Close();
        }
    }
}           

// Use parallelism here
Parallel.Foreach(rowsToEdit, currentRow =>
{
    String newValue = getWithoutUnit(currentRow.Value1.ToString());
    if (newValue != null)
    {
        // reopen connection
        // use parameters here, and call SP
    }
}

Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
Console.ReadLine();

}

存储过程:

Create StoredProcedure MySP
(
@tablename varchar(50),
@columnToFix varchar(50),
@newValue varchar(50),
@columnID varchar(50),
@tID varhcar(varchar(50)
)
As
Begin
Declare @MySQL varchar(500)
Set @MySQL = 'Update ' + @tableName + ' Set ' + @columnToFix + ' = '' + @newValue + ''' + ' Where ' + @columnID + ' = '' + @tID + '''
sp_executesql @MySQL

End

重要的是要注意动态sql通常不受欢迎。这是一个讨论动态sql(优点/缺点)的链接:http://www.sommarskog.se/dynamic_sql.html

此外,您可能会遇到一些锁定/争用问题,因为您正在点击一个表(基于该功能的输入参数)。

答案 1 :(得分:0)

首先尝试使用评论中已提到的参数。其次,使用SqlCommand.Prepare()语句。实际速度还取决于您的机器容量(HD写入速度/ RAM)。以下是示例(您可能需要根据Colum类型编辑SqlDbTypes)

    private static void RemoveUnits(string connectionString, string tableName, string columnID, string columnToFix)
    {
        Dictionary<int, string> rowsToEdit = new Dictionary<int, string>();

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();

            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;

                using (var reader = command.ExecuteReader())
                {
                    var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
                    var indexOfT_VALUE = reader.GetOrdinal(columnToFix);

                    while (reader.Read())
                    {
                        string t_value = reader.GetString(indexOfT_VALUE);
                        int t_id = reader.GetInt32(indexOfR_MEASUREDVALUEID);

                        string newValue = getWithoutUnit(t_value);
                        if (newValue != null)
                        {
                            // save values in dictionary
                            rowsToEdit[t_id] = newValue;
                        }
                    }
                }
            }

            Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
            Console.ReadLine();

            string updateCmd = "UPDATE " + tableName + " SET " + columnToFix + "= @Value WHERE " + columnID + "= @Key;";

            using (SqlTransaction transaction = connection.BeginTransaction())
            {
                SqlCommand sqlCmd = connection.CreateCommand();
                sqlCmd.CommandText = updateCmd;
                sqlCmd.Parameters.Add("@Value", System.Data.SqlDbType.NVarChar, -1);
                sqlCmd.Parameters.Add("@Key", System.Data.SqlDbType.Int);

                // important for performance
                sqlCmd.Prepare();

                foreach (var update in rowsToEdit)
                {
                    // change values of parameters
                    sqlCmd.Parameters["@Key"].Value = update.Key;
                    sqlCmd.Parameters["@Value"].Value = update.Value;

                    // and execute it
                    sqlCmd.ExecuteNonQuery();
                }

                transaction.Commit();
            }
        }
        Console.WriteLine(rowsToEdit.Count + " commands executed");
    }

编辑:如果getWithoutUnit(string)执行的操作不是很复杂,那么您可以使用TSQL执行单个语句操作,TSQL具有各种字符串操作功能。与UPDATE TableName SET StringColumn = <string manipulation TSQL here>一样,请参阅http://msdn.microsoft.com/en-us/library/ms181984.aspx

Edit2:从评论提示中添加了事务(确实应该更快),强类型列

相关问题