1

データベースの特定の設計構造が原因で、EF のパフォーマンスが非常に低下しています。関連する関係は次のとおりです。


ERD


次のデータモデルがあります。


public class Sensor
{
    [Key]
    public int Id { get; set; }

    [Required, MaxLength(64)]
    public string Name { get; set; }

    [Required, ForeignKey("Type")]
    public int SensorTypeId { get; set; }

    public virtual SensorType Type { get; set; }

    public virtual ICollection<SensorSample> SensorSamples { get; set; }
}

public class SensorSample
{
    [Key]
    public int Id { get; set; }

    [Required, ForeignKey("Sensor")]
    public int SensorId { get; set; }

    public virtual Sensor Sensor { get; set; }

    [Required]
    public DateTime SampleTime { get; set; }

    [Required]
    public virtual ICollection<SampleData> SampleData { get; set; }
}

public class SampleData
{
    [Key]
    public int Id { get; set; }

    [Required, ForeignKey("DataType")]
    public int SampleDataTypeId { get; set; }

    public virtual SampleDataType DataType { get; set; }

    [Required, ForeignKey("Unit")]
    public int SampleUnitId { get; set; }

    public virtual SampleUnit Unit { get; set; }

    [Required, ForeignKey("Sample")]
    public int SensorSampleId { get; set; }

    public virtual SensorSample Sample { get; set; }

    [MaxLength(128)]
    public string Value { get; set; }
}

SensorSampleは複数のデータ サンプル タイプ(温度、圧力など)を持つことができるため、はINSERT既存のサンプルを照会して正しい と適切に関連付ける必要がありますSampleTime。これは、次のコードを使用して行われます。


SensorSample sample = null;
foreach (var d in input)
{
    SampleData data = new SampleData();
    data.SampleDataTypeId = dataTypeId;
    data.SampleUnitId = unitId;
    data.Value = d.Value;

    // check for existing sample for this sensor and timestamp
    sample = SensorSamples.FirstOrDefault(s => s.SensorId == sensor.Id && s.SampleTime == d.Timestamp);
    if (sample == null)
    {
        // sample doesn't exist, create a new one
        sample = new SensorSample();
        sample.SampleTime = d.Timestamp;
        sample.SensorId = sensor.Id;
        sensor.SensorSamples.Add(sample);
    }
    // add the data to the sample
    sample.SampleData.Add(data);
}

サンプル データの挿入をバッチ処理 (つまり、一度に 1000 レコード) で最適化しようとしました。これは役に立ちますが、フィールドにインデックスがあっても、SampleTimeレコードが追加されるにつれてルックアップ クエリに時間がかかるようです。

私の質問は、サンプル データをデータベースに追加する際の設計やパフォーマンスを改善するにはどうすればよいかということです。一対多の関係を処理するためのより良いデータベース構造はありますか? パフォーマンスの適切なオフセットが得られるのであれば、データベースの設計についていくらか妥協しても構わないと思っていますが、それでも、特定の に関連付けられたさまざまなデータを処理できる必要がありますSampleTime

4

3 に答える 3

1

テスト データの LOAD パフォーマンスを最大化する

    DONT run project in Debug mode (multiple factor slower for EF)

次の設定を使用します。

    Context.Configuration.LazyLoadingEnabled = false;
    Context.Configuration.ProxyCreationEnabled = false;
    Context.Configuration.AutoDetectChangesEnabled = false;
    Context.Configuration.ValidateOnSaveEnabled = false;

100 エントリ以下ごとに Context を破棄します。

 Using( new context)

試す

Context.Set<TPoco>().AddOrUpdate(poco);

それ以外の

   Context.Set<TPoco>().firstorDefault(lamba);
   Context.Set<TPoco>().Add(poco);
于 2013-08-29T04:47:44.547 に答える
0

EF6 ベータ 1 には、目的に合った AddRange 関数があります。

Entity Framework 6ベータ1で多くの行を挿入する

私がリンクしている記事は、@felipeが参照しているEF5でAutoDetectChangesEnabledをfalseに設定する手法を参照していることに注意してください

于 2013-08-29T08:22:35.983 に答える