2

I have normalized a Country/region/city database into multiple tables. City has a foreign key to region which has a foreign key to country.

The CITY table includes 2 additional columns for finding the associated numerical IPAddress. As you can imagine the city table has over 4 million records (representing the cities in the world which maps back to a region and then a country).

CITY, REGION, COUNTRY are entities that I have mapped with Entity Framework power tools, that all have a name column (that represents a cityname, regionname, countryname, respectively), and a primary key IDENTITY column that is indexed.

Let's say I have a table / entity called VisitorHit that has the following columns:

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

In code I use the VisitorHit entity like:

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

now the GetAllSpecialVisitors returns a subset of the actual visitors (and it works pretty fast). The typical subset contains approximately 10,000 rows. The Select Distinct statement takes minutes to return. Ultimately I need to further delimit the distinctCountries by a date range (using the visitorhit.datevisited field) and return the count for each distinctCountry.

Any ideas on how I could speed up this operation?

4

1 回答 1

3

您是否查看过 SQL Profiler 以了解为此生成了什么 SQL。我的第一个猜测(因为您没有发布 的​​代码GetAllSpecialVisitors)是您延迟加载 City 行,在这种情况下,您将产生对数据库的多次调用(每个实例一个specialVisitors)以获取城市。您可以在调用中急切加载城市GetAllSpecialVisistors()

使用.Include("City").Include(v=>v.City)

例如像这样的东西:

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

就像我说的,您需要查看 SQL Profiler 向您显示的内容,以了解实际发送到 SQL Server 的 SQL。但是当我遇到这样的问题时,事实证明这是最常见的原因。

如果您尝试自己在 SSMS 中编写查询并且效果很好,那么另一种解决方案可能是编写视图并在视图上查询。当 Entity Framework 生成无法有效工作的笨重查询时,我有时会这样做。

于 2013-01-06T16:01:52.493 回答