【发布时间】:2012-09-22 01:10:21
【问题描述】:
我们正在使用 Entity Framework 5.0.0,数据库优先方法。
我已将几个内联表值函数 (ITVF) 导入到我的 EDMX,它们返回 IQueryable。返回后,我们最常对它们进行某种类型的操作,例如 .Skip().Take()
性能很好,至少持续了几个小时。如果不做任何事情(至少我所知道的),性能会在一夜之间下降。
首先,查询将需要大约 500 毫秒来执行。一夜之间,性能下降到查询返回超时异常(30-60 秒)的水平。这只发生在从代码执行表函数时,例如:
IQueryable<MyResult> results =
_context.MyTableFunction("searchforthis")
.Skip(currentPagingPosition*20).Take(20);
(这不仅仅是我们第一次运行查询时会发生这种情况)
如果我们直接从 SQL Server Management Studio 运行相同的表函数,查询将在大约 500 毫秒内执行。
如果我像这样“重新保存”表格函数:
ALTER FUNCTION [dbo].[MyTableFunction]......
无需进行任何“真正的”更改,即使从代码中调用,它也会立即恢复到 500 毫秒的速度。
我是否遗漏了一些明显的东西,有什么想法吗?
【问题讨论】:
-
性能问题是否体现在应用程序的 CPU/内存使用率较高?
-
@LukeMcGregor - 不,它可以通过单个参数发生。发生这种情况是因为 SQL Server 为传递的第一个参数值编译了一个计划,然后将其缓存并将其重用于所有其他调用。如果该参数不具代表性(例如高度选择性),则所使用的计划对于应用程序传递的其他可能参数值可能是灾难性的。像 OP 一样运行
ALTER FUNCTION将从缓存中删除坏计划,因此为什么要修复它。 -
您可以尝试使用
OPTIMIZE FOR UNKNOWN。尽管您可能必须通过 plan guide 来执行此操作,因为 EF 正在生成 TSQL。
标签: c# sql-server entity-framework