1

私の SQL コードは、リストからテーブルに 10,000 レコードを挿入します。レコードが既に存在する場合は、いくつかのフィールドを更新します。

現在、処理するレコードの数を制限しない限り、10 分以上かかり、タイムアウトになります。この問題を解決するために私のコードにできることはありますか?

   foreach(RMSResponse rmsObj in rmsList) {
        try {
            string connectionString = @"server=localhost\sqlexpress;" + "Trusted_Connection=yes;" + "database=MyDB; " + "connection timeout=30";

            SqlConnection conn = new SqlConnection(connectionString);
            conn.Open();

            string str = "";
            str += "SELECT * ";
            str += "FROM RMSResponse ";
            str += "WHERE LeadID = @RecruitID";
            int LeadID;
            Boolean IsPositive = true;

            SqlCommand selectCommand = new SqlCommand(str, conn);
            selectCommand.CommandType = CommandType.Text;
            selectCommand.Parameters.Add(new SqlParameter("@RecruitID", rmsObj.RecruitID));
            SqlDataReader sqlDataReader = selectCommand.ExecuteReader();
            bool hasRows = sqlDataReader.HasRows;

            while (sqlDataReader.Read()) {
                LeadID = sqlDataReader.GetInt32(1);
                IsPositive = sqlDataReader.GetBoolean(2);
                IsPositive = (IsPositive == true) ? false : true;
                Console.WriteLine("Lead ID: " + LeadID + " IsPositive: " + IsPositive);
            }

            sqlDataReader.Close();

            if (hasRows) {
                SqlCommand updateCommand = new SqlCommand("UPDATE RMSResponse set IsPositive=@IsPositive, OptOutDate=@OptOutDate where LeadID=@LeadID", conn);
                updateCommand.Parameters.AddWithValue("@LeadID", rmsObj.RecruitID);
                updateCommand.Parameters.AddWithValue("@IsPositive", IsPositive);
                updateCommand.Parameters.AddWithValue("@OptOutDate", DateTime.Now);
                updateCommand.ExecuteNonQuery();
                sqlDataReader.Close();
            }

            if (!hasRows) {
                SqlCommand insertCommand = new SqlCommand("INSERT INTO RMSResponse (LeadID, IsPositive, ReceivedDate) " + "VALUES(@LeadID, @IsPositive, @ReceivedDate)", conn);
                insertCommand.Parameters.AddWithValue("@LeadID", rmsObj.RecruitID);
                insertCommand.Parameters.AddWithValue("@IsPositive", true);
                insertCommand.Parameters.AddWithValue("@ReceivedDate", DateTime.Now);
                int rows = insertCommand.ExecuteNonQuery();
            }
        } catch (SqlException ex) {
            Console.WriteLine(ex.Message);
        }
    }
4

2 に答える 2

2

更新を SQL に移行できます。OptOutDate を今日に設定するだけです。リード ID のリストをバッチ更新ステートメントに渡すことができます。

レコードを挿入するには、ステージング テーブルに一括挿入してから、SQL を実行して、まだテーブルにない ID のデータを挿入します。

C# には多くのロジックがないため、データを取り出してから戻すと、不必要に遅くなります。


このルートをたどりたくない場合は、他のヒントを以下に示します。

  • ループの外側で 1 つの接続を開きます
  • ループの外側で 1 つの SqlCommand オブジェクトを作成し、パラメーターをリセットして再利用します。
  • select SQL を変更して、* ではなく、必要な列のみを選択するようにします。
于 2012-07-11T08:11:44.670 に答える
2

単純な update または insert ステートメントに 10 分もかからないようにしてください。

SqlServer は非常に優れたデータベースです。

テーブル RMSResponse の LeadID にインデックスを作成します。

foreach が多くのレコードをループしている場合は、必ずストアド プロシージャを検討してください。ストアド プロシージャは、かかる時間を大幅に短縮します。

Update または Insert(UPSERT) を行う場合は、SqlServer 2008 で追加されたMergeコマンドを参照してください。

于 2012-07-11T08:13:22.847 に答える