質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

解決済

C#でTaskを使ってINSERTやUPDATEを繰り返していくと段々遅くなる

asral
asral

総合スコア10

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

2回答

0評価

0クリップ

251閲覧

投稿2022/06/24 03:21

編集2022/07/01 17:46

前提

Visual Studio 2019 
フレームワーク: .NET core 3.1
コンソールアプリケーション

C#でTaskを使って複数のINSERTやUPDATEを繰り返すと、徐々に1件登録・更新を続けていくと少しずつ遅くなってしまいます。最初の数十件は1件目から2件目登録するのにそれほど時間はかかりませんが、数百件目となると1件処理するのに数秒かかるようになりました。
登録や更新しているDBはLocalに構築しています。

実現したいこと

可能であれば、この遅くなる現象が少しでも解消できればと思います。

発生している問題

1件目:00:00:00.86 2件目:00:00:00.73 ~ 100件目:00:00:01.54 101件目:00:00:01.44 ~ 200件目:00:00:03.16 201件目:00:00:03.28

該当のソースコード

C#

private static async Task<bool> ExitPrintImageMain() { try { int listcnt = 0; foreach (var v in TestList) { await UpdTest1TransactionAsync(listcnt); await InsTest1TransactionAsync(listcnt); await InsTest2TransactionAsync(listcnt); await InsTest3TransactionAsync(listcnt); await UpdTest2TransactionAsync(listcnt); await UpdTest3TransactionAsync(listcnt); await UpdTest4TransactionAsync(listcnt); await InsTest4TransactionAsync(listcnt); await UpdTest4TransactionAsync(listcnt); await InsTest5TransactionAsync(listcnt); await InsTest6TransactionAsync(listcnt);        listcnt = listcnt + 1; } return true; } catch (Exception e) { Console.WriteLine(System.DateTime.Now + " : " + e.Message); return false; } }

パラメータはもっと沢山ありますが、一部のみ記述しています。

C#

private static async Task InsTest1TransactionAsync(int listcnt) { try { DateTime dt = DateTime.Now; parameter1.iTest_NO = listcnt; parameter1.sTest_TIME = dt.ToString("yyyy/MM/dd HH:mm:ss") await Tracsaction.Ins1Main(); } catch (Exception e) { Console.WriteLine(System.DateTime.Now + " : " + e.Message); Log.PrintOut(System.DateTime.Now + " : " + e.Message, true); } }

C#

private static bool Ins1Main() { MySqlCommand cmd = new MySqlCommand(SQL.ins1, cn); try { cmd.Parameters.Add(new MySqlParameter("i0", Program.parameter1.iTest_NO)); cmd.Parameters.Add(new MySqlParameter("s1", Program.parameter1.sTest_TIME)); cmd.Transaction = cn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted); cmd.ExecuteNonQuery(); cmd.Transaction.Commit(); cmd.Connection.Close(); cmd.Dispose(); return true; } catch (Exception e) { Console.WriteLine(System.DateTime.Now + " : " + e.Message + Environment.NewLine + "Execution RollBack Start!!"); cmd.Transaction.Rollback(); return false; } }

C#

public const string ins1 = "INSERT tbl_test (Test_NO,Test_Time) VALUES(@i0,@s1)"

試したこと

Taskを使用せず同期処理に戻したりもしましたが、結果は変わりませんでした。

何らかのバッファが溜まってるのか、コネクションプール等も関係しているのかと思いましたが、改善点が分からなかったのでここで質問させていただきました。

よろしくお願いいたします。

補足情報

windows10
mysql5.6.20

上記のソースから指摘されたところを変更したソース

ひとまずcatchは省いています。以下はINSERTのみですが、UPDATEも同じように直しました。

C#

private static async Task<bool> ExitPrintImageMain() { try { int listcnt = 0; foreach (var v in TestList) { await UpdTest1TransactionAsync(listcnt); await InsTest1TransactionAsync(listcnt);        listcnt = listcnt + 1; } return true; } }

parameter2~5は省いています。実際はちゃんと記述してます。

C#

private static async Task InsTest1TransactionAsync(int listcnt) { try { DateTime dt = DateTime.Now; parameter1.iTest_NO = listcnt; parameter1.sTest_TIME = dt.ToString("yyyy/MM/dd HH:mm:ss") parameter6.iTest_NO = listcnt; parameter6.sTest_TIME = dt.ToString("yyyy/MM/dd HH:mm:ss") await Tracsaction.Ins1Main(); }    }

C#

private static bool Ins1Main() { MySqlCommand cmd = new MySqlCommand(SQL.ins1, cn); try { cmd.Parameters1.Add(new MySqlParameter("i0", Program.parameter1.iTest_NO)); cmd.Parameters1.Add(new MySqlParameter("s1", Program.parameter1.sTest_TIME)); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); cmd = new MySqlCommand(SQL.ins6, cn); cmd.Parameters6.Add(new MySqlParameter("i0", Program.parameter6.iTest_NO)); cmd.Parameters6.Add(new MySqlParameter("s1", Program.parameter6.sTest_TIME)); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); cmd.Transaction = cn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted); cmd.Transaction.Commit(); cmd.Connection.Close(); cmd.Dispose(); return true; } }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

Zuishin

2022/06/24 03:35

InsTest1TransactionAsync に await が無いので同期処理になっています。 Task は無関係のように思いますから、それを条件から外して考えてみてください。 インデックスを作っているか確かめたり、接続と切断をまとめてみたりすれば解決策がつかめるかもしれません。
SurferOnWww

2022/06/24 03:41

質問する際は何を何で作っているかを質問の一行目に書きましょう。(例: C# のコンソールアプリを Visual Studio 2022 でフレームワークを .NET Framework 4.8 として作っています・・・とか) 数百件も INSERT するなら、そもそものやり方が適してないのでは? バルクインサートなど、DB とのラウンドトリップ回数を減らすことを考える余地はないのですか? 非同期になっているようには見えないのですが、ちょっとそこは置いといて、非同期に何を期待してますか? コードを見る限り非同期だから早くなるということはなさそうに見えますが。
asral

2022/06/24 03:51

ありがとうございます。改修しておきます。 インデックスは各テーブルにはいくつか張っていますが、再度確認してみます。 やはり接続か切断ですかね・・・。毎回OPENしてcloseとdisposeすると確かに遅くなるみたいなのは見ましたが・・・。
KOZ6.0

2022/06/24 04:43

cmd.Connection.Close(); で、毎回切断しているように見えますが、意図的なものでしょうか?
asral

2022/06/24 06:01

>KOZ6.0様 毎回接続と切断しているのは意図的です。
KOZ6.0

2022/06/24 06:23 編集

SQL を実行するたびに Open/Close しているわけですね? コネクションプールで接続は残っていますが、そのたびにサーバーに対して生きているかどうか問い合わせを行うはずです。サーバー側の負荷が大変なことになりそうですが・・・ 1回の接続で 1000 回や 2000回の SQL を実行したところでそれほど遅くなるとは思えません。 Open/Close のタイミングを見直してみてはいかがでしょうか。
SurferOnWww

2022/06/26 23:12

質問者さん、その後無言ですが、回答を試して望む改善は得られたでしょうか。フィードバックをお願いします。回答が役に立たなかったならどこがダメかを書くと別の提案が出てくるかも。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。