0

インバータからの情報を約15分ごとに記録したテーブルがあります。インバーターが送信するデータの1つは、そのkwhtotalインバーターを介して生成された総電力量を表す数値です。特定の日に生成された電力を取得するためのクエリを正しく取得しようとしています。そのためには、前日の最後の読みを取得し、それを当日の最後の読みと比較する必要があります。

これが私がこれまでに持っているものです:

DateTime prevStartD = new DateTime((utcStartingDate.AddDays(i - 1)).Year, (utcStartingDate.AddDays(i - 1)).Month, (utcStartingDate.AddDays(i - 1)).Day, 0, 0, 0);
DateTime prevEndD = new DateTime((utcStartingDate.AddDays(i - 1)).Year, (utcStartingDate.AddDays(i - 1)).Month, (utcStartingDate.AddDays(i - 1)).Day, 23, 59, 59);

var previousDay = (from s in db.PowerInverterHistorys
                   join u in db.PowerInverters on s.inverter_id equals u.id
                   where u.name == record && (s.recordTime >= prevStartD && s.recordTime <= prevEndD)
                   orderby s.recordTime descending
                   select new
                   {
                       s.recordTime,
                       s.kwhtotal
                   }).Take(1);

DateTime currStartD = new DateTime((utcStartingDate.AddDays(i)).Year, (utcStartingDate.AddDays(i)).Month, (utcStartingDate.AddDays(i)).Day, 0, 0, 0);
DateTime currEndD = new DateTime((utcStartingDate.AddDays(i)).Year, (utcStartingDate.AddDays(i)).Month, (utcStartingDate.AddDays(i)).Day, 23, 59, 59);

var currentDay = (from s in db.PowerInverterHistorys
                  join u in db.PowerInverters on s.inverter_id equals u.id
                  where u.name == record && (s.recordTime >= currStartD && s.recordTime <= currEndD)
                  orderby s.recordTime descending
                  select new
                  {
                      s.recordTime,
                      s.kwhtotal
                  }).Take(1);

double? pDay = 0, cDay = 0;
foreach (var p in previousDay) { pDay = p.kwhtotal; }
foreach (var c in currentDay) { cDay = c.kwhtotal; }

var generatedPower = cDay - pDay;

動作して実行されますが、非効率的です。実行時にページが開くまでに非常に長い時間がかかります。 このクエリを高速化するためにできることはありますか?私がする必要があるのは、当日の最後のエントリkwhtotalのから前日の最後のエントリのを引くことkwhtotalです。

4

2 に答える 2

1

制限s.recordTime>=prevStartD && s.recordTime <= currEndDを使用し、Take(1)を使用せずに、2つのクエリを1つに結合できますか。これは、データベースへのトリップが2回ではなく1回だけであることを意味します。データセットを取り戻したら、s.recordTime <= prevEndD条件を使用してローカルでこれらの結果をクエリし、pDay値を見つけてから、s.recordTime> = currStartD条件で再度クエリを実行し、最後のレコードを調べてcDayを取得します。価値。

于 2012-08-01T21:33:15.347 に答える
0
var previousDay = (from s in db.PowerInverterHistorys
                   join u in db.PowerInverters on s.inverter_id equals u.id
                   where u.name == record && (s.recordTime >= prevStartD && s.recordTime <= prevEndD)
                   orderby s.recordTime descending
                   select new
                   {
                       s.recordTime,
                       s.kwhtotal
                   }).Take(1);

大規模なデータセットがある場合、OrderByはDBにとってコストのかかる操作です。代わりにMax()またはMin()を使用すると、常に対応する最初の行がuに与えられます。これは、「CurrentDay」クエリにも適用されます。

于 2012-08-02T12:24:07.203 に答える