Not*_*Dan 16 .net c# linq-to-entities entity-framework
下面的executeTime是第一次30秒,下次执行同一组代码时是25秒.在SQL Profiler中观看时,我立即看到一个登录,然后它就在那里坐了大约30秒.然后,只要运行select语句,应用程序就会完成ToList命令.当我从Management Studio运行生成的查询时,数据库查询只需要大约400毫秒.它返回14行和350列.看起来像将数据库结果转换为实体所花费的时间非常小,不值得注意.
那么在数据库调用之前的30秒内发生了什么?
如果实体框架这么慢,我们就不可能使用它.有什么我做错了或者我可以改变什么来加速这一点吗?
更新: 好吧,如果我使用编译查询,第一次需要30秒,第二次需要1/4秒.有什么办法可以加快第一次通话的速度吗?
using (EntitiesContext context = new EntitiesContext())
{
Stopwatch sw = new Stopwatch();
sw.Start();
var groupQuery = (from g in context.Groups.Include("DealContract")
.Include("DealContract.Contracts")
.Include("DealContract.Contracts.AdvertiserAccountType1")
.Include("DealContract.Contracts.ContractItemDetails")
.Include("DealContract.Contracts.Brands")
.Include("DealContract.Contracts.Agencies")
.Include("DealContract.Contracts.AdvertiserAccountType2")
.Include("DealContract.Contracts.ContractProductLinks.Products")
.Include("DealContract.Contracts.ContractPersonnelLinks")
.Include("DealContract.Contracts.ContractSpotOrderTypes")
.Include("DealContract.Contracts.Advertisers")
where g.GroupKey == 6
select g).OfType<Deal>();
sw.Stop();
var queryTime = sw.Elapsed;
sw.Reset();
sw.Start();
var groups = groupQuery.ToList();
sw.Stop();
var executeTime = sw.Elapsed;
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*row 13
我有同样的问题,我的查询需要40秒.
我发现问题出在.Include("table_name")功能上.我拥有的越多,它就越糟糕.相反,我在查询后立即将我的代码更改为Lazy Load所需的所有数据,这将总时间从40秒减少到大约1.5秒.据我所知,这完成了同样的事情.
所以对于你的代码,它将是这样的:
var groupQuery = (from g in context.Groups
where g.GroupKey == 6
select g).OfType<Deal>();
var groups = groupQuery.ToList();
foreach (var g in groups)
{
// Assuming Dealcontract is an Object, not a Collection of Objects
g.DealContractReference.Load();
if (g.DealContract != null)
{
foreach (var d in g.DealContract)
{
// If the Reference is to a collection, you can just to a Straight ".Load"
// if it is an object, you call ".Load" on the refence instead like with "g.DealContractReference" above
d.Contracts.Load();
foreach (var c in d.Contracts)
{
c.AdvertiserAccountType1Reference.Load();
// etc....
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
顺便提一下,如果你要在当前代码中将这行代码添加到查询之上,它会将时间缩短到大约4-5秒(在我的选项中仍然过于敏感)从我的理解,该MergeOption.NoTracking选项禁用了很多用于更新和插入数据库的跟踪开销:
context.groups.MergeOption = MergeOption.NoTracking;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18393 次 |
| 最近记录: |