2

国/地域/都市データベースを複数のテーブルに正規化しました。都市には、国への外部キーを持つ地域への外部キーがあります。

CITYテーブルには、関連付けられた数値を検索するための 2 つの追加の列が含まれていますIPAddress。ご想像のとおり、city テーブルには 400 万を超えるレコードがあります (世界の都市を表し、地域と国にマップされます)。

CITYREGIONCOUNTRYは、Entity Framework パワー ツールでマップしたエンティティであり、すべて名前列 (それぞれcitynameregionnamecountrynameを表す) と、インデックスが作成された主キー IDENTITY 列があります。

VisitorHit次の列を持つテーブル/エンティティがあるとします。

id as int (primary key, identity)
dateVisited as datetime 
FK_City as int (which has a many to one relationship to the CITY entity)

コードでは、次のVisitorHitようなエンティティを使用します。

var specialVisitors = VisitorRepository.GetAllSpecialVisitors();
var distinctCountries = specialVisitors.Select(i => i.City.CityName).Distinct().ToArray();

これGetAllSpecialVisitorsで、実際の訪問者のサブセットが返されます (そして、かなり高速に動作します)。一般的なサブセットには、約 10,000 行が含まれます。ステートメントが返されるSelect Distinctまでに数分かかります。distinctCountries最終的には、(フィールドを使用して) 日付範囲でさらに区切り、visitorhit.datevisited各 のカウントを返す必要がありますdistinctCountry

この操作を高速化する方法についてのアイデアはありますか?

4

1 に答える 1

3

SQL Profiler を見て、このために生成されている SQL を確認しましたか。私の最初の推測 ( のコードを投稿していないためGetAllSpecialVisitors) は、City の行を遅延読み込みしているということです。その場合、都市を取得するためにデータベースへの複数の呼び出し ( のインスタンスごとに 1 つspecialVisitors) を生成することになります。への呼び出しで都市を熱心にロードできますGetAllSpecialVisistors()

.Include("City")または_.Include(v=>v.City)

たとえば、次のようなもの:

var result = from hit in context.VisitorHits
             where /* predicates */
             .Include(h =>h.City)

前述したように、実際に SQL Server に送信されている SQL を確認するには、SQL プロファイラーが表示しているものを確認する必要があります。しかし、このような問題が発生すると、それが最も一般的な原因であることが判明します。

SSMS で自分でクエリを作成しようとして、それがうまく機能する場合は、別の解決策として、ビューを作成し、ビューに対してクエリを実行することができます。これは、Entity Framework が効率的に機能しない扱いにくいクエリを生成する場合に、私が行った別のことです。

于 2013-01-06T16:01:52.493 に答える