我已将国家/地区/城市数据库规范化为多个表格。城市拥有对国家具有外键的地区的外键。
CITY
表包含2个附加列,用于查找关联的数字IPAddress
。你可以想象,城市表有超过400万条记录(代表世界上的城市,它们映射回一个地区,然后是一个国家)。
CITY
,REGION
,COUNTRY
是我使用Entity Framework电源工具映射的实体,它们都有一个名称列(代表cityname
,{{分别为1}},regionname
,以及索引的主键IDENTITY列。
假设我有一个名为countryname
的表/实体,其中包含以下列:
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();
返回实际访问者的子集(并且它的工作速度非常快)。典型的子集包含大约10,000行。 GetAllSpecialVisitors
语句需要几分钟才能返回。最后,我需要进一步将Select Distinct
分隔一个日期范围(使用distinctCountries
字段)并返回每个visitorhit.datevisited
的计数。
关于如何加快这项行动的任何想法?
答案 0 :(得分:2)
您是否查看了SQL事件探查器以查看为此生成的SQL。我的第一个猜测(因为你没有发布GetAllSpecialVisitors
的代码)将是你懒惰加载City行,在这种情况下你将产生对数据库的多个调用(对于{中的每个实例一个) {1}})获得城市。您可以在致电specialVisitors
时急切加载城市。
使用GetAllSpecialVisistors()
或.Include("City")
e.g。像这样:
.Include(v=>v.City)
就像我说的那样,您需要查看SQL Profiler向您展示的内容,以了解SQL实际发送到SQL Server的内容。但是当我遇到这样的问题时,结果却是最常见的原因。
如果您尝试在SSMS中自己编写查询并且它运行良好,那么另一种解决方案可能是在视图上编写视图和查询。当Entity Framework产生难以有效工作的笨重查询时,我还是偶尔做过这件事。