多くのテストを行った結果、問題はEntity FrameworkまたはNpgSqlにはまったくないことがわかりましたが、表示された遅延は書き込みキャッシュが原因でした。テーブル1に行を挿入する前に常に30MBのファイルを書き込んでいましたが、ファイルの書き込みはFile.WriteAllBytesが返された後に行われるため、将来のタイミングステートメントに影響を与えないと考えていました。ただし、OSレイヤーでは、挿入ステートメントが実行されるまでにディスクへの書き込みが実際には行われていなかったため、挿入ステートメントが人為的に遅延していました。
私はこれを次のコードで証明しました:
Stopwatch sw1 = new Stopwatch();
sw1.Start();
File.WriteAllBytes(myBytes);
sw1.Stop();
Thread.Sleep(1000);
Stopwatch sw2 = new Stopwatch();
sw2.Start();
MethodThatInsertsIntoTable1();
sw2.Stop();
ストップウォッチ1は、File.WriteAllBytesが常に約500ミリ秒かかり、ストップウォッチ2が約20〜30秒かかることを示しました。
MethodThatInsertsIntoTable1を変更して別のテーブルに挿入した場合でも、テーブルに関係なく20〜30秒かかります。
Thread.Sleep(1000)をThread.Sleep(30000)に増やすと、ストップウォッチ2は、挿入に10ミリ秒未満かかることを記録します。
これは、File.WriteAllBytesがプログラムに制御を戻した後でも、実際にはファイルをディスクに書き込んでいないことを示しています。
私が実行していた環境は、ラズベリーパイ上のLinuxでした。書き込み速度テストでは、SDカードへの書き込み速度が1MB /秒をわずかに超えていることを確認しています。これは、30MBのファイルを書き込むのに20〜30秒かかり、500ミリ秒では実行できなかった可能性があります。そのストップウォッチ1はそうだったと言っています。
別のユーザーは、File.WriteAllBytesでこれが原因で問題が発生しているようです。ブロックしない
外付けSSDUSBHDDをラズベリーパイに追加し、代わりにファイルをそこに保存するように変更した後、ファイルの保存には0.5秒しかかからず、問題は解決します。