C# SQL Server选择低效计划(通过EntityFramework)

C# SQL Server选择低效计划(通过EntityFramework),c#,sql,sql-server,entity-framework,C#,Sql,Sql Server,Entity Framework,抱歉,这篇文章太长了,没有图片很难描述这个问题。简单地说,SQL对同一查询使用不同的查询计划(取决于我是否使用参数)。我知道这是参数嗅探的一个问题,但由于我使用的是实体框架,我没有办法在查询中使用提示 表格设计 下面是表格设置的图片(在本例中我只使用了几个字段) 示例查询 市场项目表说明: TypeID和LastSeen都被索引。Expired是一个位字段。 平均而言,约有40000件物品未过期,约有4mil+已过期(这根本不重要) 项目属性表说明: 对于item attributes表,只有

抱歉,这篇文章太长了,没有图片很难描述这个问题。简单地说,SQL对同一查询使用不同的查询计划(取决于我是否使用参数)。我知道这是参数嗅探的一个问题,但由于我使用的是实体框架,我没有办法在查询中使用提示

表格设计 下面是表格设置的图片(在本例中我只使用了几个字段)

示例查询 市场项目表说明: TypeID和LastSeen都被索引。Expired是一个位字段。 平均而言,约有40000件物品未过期,约有4mil+已过期(这根本不重要)

项目属性表说明: 对于item attributes表,只有主键(Id)被索引,大约有20000条记录

问题 当EF在查询中使用一个参数并且查询空数据需要6秒钟以上时,就会发生这种情况,通常情况下,空数据几乎是即时的。即使我在attributes表中搜索一个不存在的名称,完成查询也需要大约6秒钟。它似乎正在遍历所有市场项目,并且每次都在属性表中进行文本查找

糟糕的执行计划 这是带参数的查询计划(无数据运行需要6-7秒)

完整资源链接:

良好的执行计划 这里是完全相同的查询,没有参数(当然,对于任何字符串或项目,都会立即运行):

完整资源链接:

所以,问题要么是SQL为什么会生成如此糟糕的计划,要么是我如何强制EF(6.1)使用不同的计划或接受查询提示。 关于如何解决这个问题,我愿意接受任何其他建议


谢谢大家!

很难对merrit做出任何假设,即优化器为什么在没有执行计划的完整XML以及相关统计数据的情况下生成这个或那个计划

然而,你也问了如何强制使用一个特定的计划,对此有一个答案

使用计划指南告诉优化器要做什么。使用特定查询的计划指南,您可以指定某些优化器提示,甚至可以指定整个执行计划。如果缓存中有一个好的计划,那么使用计划指南修复它是非常容易的

这些都在网上的书中得到了很好的解释:


您也可以启用强制参数化,但要小心,并进行彻底的测试,因为它是数据库范围内的设置,无论好坏都会影响每个查询。

您是否尝试过启用强制临时参数化和基准测试?您是否确保统计数据是最新的?是的,我重建了所有索引,并更新了所有统计数据。我现在还将研究临时参数化和bechmarking:其中attr.Name(如“%item\u Name%”)可能会阻止使用任何可用的索引。Name是Nvarchar列吗?是的,这不会有什么区别,是吗?只有2万张左右的唱片需要搜索谢谢,我来看看
    SELECT TOP 10 * FROM MarketItems mk
    JOIN ItemAttributes attr ON mk.TypeId == attr.Id
    WHERE attr.Name LIKE '%item_name%' AND Expired = 0
    ORDER BY mk.LastSeen DESC