我目前遇到的问题是,在数据库中为1种EF查询方式创建了数千个计划。
查询本身是参数化的,但参数名称不断变化,因此文本不同,因此每次查询到达我的数据库服务器时都会产生新的编译。
所以查询看起来像这样。
(@p__linq__100687 int)SELECT [Extent1].[MyColumn] From MyTable [Extent1]
Where Column1 = @p__linq__100687
,下一个看起来像这样
(@p__linq__100688 int)SELECT [Extent1].[MyColumn] From MyTable [Extent1]
Where Column1 = @p__linq__100688
我希望EF做的是
(@p__linq__1 int)SELECT [Extent1].[MyColumn] From MyTable [Extent1]
Where Column1 = @p__linq__1
然后继续重复使用上面的查询,而不是递增,然后继续 被迫制定新计划。
因此,当我浏览数据库上的计划缓存时,我总共获得了7GB的计划,这些计划只使用过一次。
我是一名DBA,需要弄清楚要告诉供应商Devs,因为他们坚持认为这是按照MS实施EF的正确方法。
我搜索了谷歌,并在背景中询问了几个开发者朋友围绕代码的构建,但答案仍然存在。
答案 0 :(得分:0)
我刚刚使用VS 2017和EF 6进行了一些测试,并且没有遇到任何问题,甚至尝试了一些糟糕的c#代码。
我试过了:
AdventureWorks2016Entities ctx = new AdventureWorks2016Entities();
for (var i = 1; i <= 50; i++)
{
var query = (from x in ctx.bigProduct.AsNoTracking()
where x.ReorderPoint == i
select x);
var result = query.ToList();
}
和此:
for (var i = 1; i <= 50; i++)
{
AdventureWorks2016Entities ctx = new AdventureWorks2016Entities();
var query = (from x in ctx.bigProduct.AsNoTracking()
where x.ReorderPoint == i
select x);
var result = query.ToList();
}
第一个代码块在每次迭代中重新创建查询,第二个代码块也在每次迭代中重新创建上下文。这些选项都没有创建您正在遭受的计划缓存膨胀。
您的应用程序使用的EF版本是什么?
但是,我在EF中发现了十进制类型的这个问题。我刚刚发布了一个关于此的问题,你可以在这里找到它 - How to avoid plan cache bloat using queries in entity framework