3つのテーブル(Worker、Task、TaskStep)でデータベースを使用するプログラムを構築しています。タスクの特定のワーカーの日付を取得してレポートを作成し、特定の日のステップを実行するメソッドがあります。
データベースの構造は次のとおりです。
MySQL 5.2
Worker
テーブル列:
workerID(VARCHAR(45)),
name(VARCHAR(45)),
age(int),
...
Tasks
テーブル列:
TaskID(VARCHAR(45)),
description(VARCHAR(45)),
date(DATE),
...
TaskSteps
テーブル列:
TaskStepID(VARCHAR(45)),
description(VARCHAR(45)),
date(DATE),
...
どのテーブルにもインデックスはありません
問題はそれが非常に遅いということです!! (〜20秒)
コードは次のとおりです。
using WorkerDailyReport = Dictionary<task, IEnumerable<taskStep>>;
private void Buildreport(DateTime date)
{
var report = new WorkerDailyReport();
// Load from DB
var sw = new Stopwatch();
sw.Start();
var startOfDay = date.Date;
var endOfDay = startOfDay.AddDays(1);
var db = new WorkEntities();
const string workerID = "80900855";
IEnumerable<task> _tasks = db.task
.Where(ta => ta.date >= startOfDay &&
ta.date < endOfDay &&
ta.workerID == workerID)
.ToList();
sw.Stop();
Console.WriteLine("Load From DB time - " + sw.Elapsed +
", Count - " + _tasks.Count());
// Build the report
sw.Restart();
foreach (var t in _tasks)
{
var ts = db.taskStep.Where(s => s.taskID == task.taskID);
report.Add(t, ts);
}
sw.Stop();
Console.WriteLine("Build report time - " + sw.Elapsed);
// Do somthing with the report
foreach (var t in report)
{
sw.Restart();
foreach (var subNode in t.Value)
{
// Do somthing..
}
Console.WriteLine("Do somthing time - " + sw.Elapsed +
", Count - " + t.Value.Count());
}
}
あなたが見ることができるように、私はストップウォッチを各部分に置いて、何がそんなに時間がかかるかをチェックします、そしてこれは結果です:
1)
上記のようにコードを実行した場合:
コンソール:
Load From DB time - 00:00:00.0013774, Count - 577
Build report time - 00:00:03.6305722
Do somthing time - 00:00:07.7573754, Count - 21
Do somthing time - 00:00:08.2811928, Count - 11
Do somthing time - 00:00:07.8715531, Count - 14
Do somthing time - 00:00:08.0430597, Count - 0
Do somthing time - 00:00:07.7867790, Count - 9
Do somthing time - 00:00:07.3485209, Count - 39
.........
内側のforeach実行には約7〜9かかります!! 40レコードを超えないようにするための秒。
2)
1つだけ変更する場合は、データベースからワーカータスクをロードするときに、最初のクエリの後に.ToList()を追加すると、すべて変更されます。
コンソール:
Load From DB time - 00:00:04.3568445, Count - 577
Build report time - 00:00:00.0018535
Do somthing time - 00:00:00.0191099, Count - 21
Do somthing time - 00:00:00.0144895, Count - 11
Do somthing time - 00:00:00.0150208, Count - 14
Do somthing time - 00:00:00.0179021, Count - 0
Do somthing time - 00:00:00.0151372, Count - 9
Do somthing time - 00:00:00.0155703, Count - 39
.........
現在、データベースからのロードにはさらに多くの時間がかかり、4秒以上かかります。ただし、ビルドされたレポート時間は約1ミリ秒で、各内部foreachには約10ミリ秒かかります
最初の方法は不可能であり(577 *〜8秒)、2番目のオプションも非常に遅く、yが表示されません。
ここで何が起こっているのか分かりますか?
1)なぜToList()
そんなに遅いのですか?
2)なぜToList()
、内部foreach
レポートとビルドレポートが遅くなっているのですか?
どうすれば速くできますか?
thnx。