2016-12-08 14 views
1

私はASP.NET MVC 5アプリケーションを構築して、一度にいくつかのレコード(2行から12行の間)に読み取り専用アクセスを取得します。レコードはOracle 11に格納され、Oracleの大きなキーなしのマテリアライズド・ビューからEntity Framework 6を​​介してアクセスされます。 List、IQueryable、IEnumerableでこれらのレコードを取得しようとしました。 (下記の例)Entity FrameworkのOracleマテリアライズドビューから10レコードを取得するVERY slow

public List<FACT> GetCollisionList(string collisionMRN) 
{ 
    var collisions = from c in _context.FACT 
        where c.COLLISION_RECORD_NUMBER.Equals 
        (DbFunctions.AsNonUnicode(collisionMRN), 
        StringComparison.OrdinalIgnoreCase) 
         select c; 

    return collisions.ToList(); 
} 

レコードを返すのに約20秒かかっています。私の質問は次のとおりです。A.これらの3つの方法のうち、おそらく最も良いのは何ですか? (List、IQueryable、IEnumerable)------ B.キーなしのマテリアライズド・ビューは基本的な問題ですか? (私は.NETデータリポジトリにモデルを持っていますが、ビューに含まれる100以上の列のうち8つしか使用しません)。

答えて

0

あなたのお問い合わせで以下のようにお試しください。

注:は、AsNoTracking()を使用してレイジーローディングを削除します。

AsNoTracking():

は、あなたがより多くのオプションを学ぶために、このドキュメントを読むことができます

public List<FACT> GetCollisionList(string collisionMRN) 
{ 

_context.Configuration.LazyLoadingEnabled = false;//to remove lazy loading 

var collisions = (from c in _context.FACT 
        where c.COLLISION_RECORD_NUMBER.Equals 
        (DbFunctions.AsNonUnicode(collisionMRN), 
        StringComparison.OrdinalIgnoreCase) 
         select c).AsNoTracking(); 

return collisions.ToList(); 

} 

エンティティが にキャッシュされることはありませんDbContext

を返された新しいクエリを返します。クエリの最適化について: Performance Considerations for EF

+0

このご意見は、 – Sampath

+0

これは良い答えです!私はまだOracle側を変更するためにどのような選択肢があるかを見極めています。 –

+1

ありがとうございました!非常に役立つ答えはこちら。 SampathとKacperはともにこの問題に非常に役立っていました。 –

0

ビューにwhere句で使用される列の主キーも索引もない場合、これは実際問題です。索引OracleがMVをフルスキャンする必要がない場合したがって、MVのインデックスを作成することを検討する必要があります。

これらの100個のカラムにデータを取り込むのに時間がかかる場合は、必要なカラムだけを選択してビューをクエリするMV上のビューを作成することを検討する必要があります。しかし、これはあまり役に立ちません(列がBLOBまたはCLOBまたは他の巨大な型でない限り)。主な問題は指数ではないようです。

クエリの実行計画を生成し、クエリのMVと推定コストにアクセスする方法を確認する必要があります。

関連する問題