下面是表格设置的图片(本例中我只使用了几个字段)
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
TypeID和LastSeen都被编入索引。过期是一个有点领域。 平均而言,大约有大约40,000个项目未过期,且大约4个月到期(这不应该是重要的)。
对于项目属性表,仅索引主键(Id),并且大约有大约20,000条记录。
当EF在查询中使用参数并且查询空数据需要6秒以上时,会发生这种情况,通常情况下它几乎是即时的。即使我在属性表中搜索非退出名称,查询也需要大约6秒钟才能完成。它似乎经历了所有市场项目,并且每次都在Attributes表中进行文本查找。
以下是带参数的查询计划(无数据运行需要6-7秒)
完整资源链接:https://puu.sh/8fNKy/2a98367722.png
这是完全相同的没有参数的查询(当然,对于任何字符串或项目立即运行):
完整资源链接:https://puu.sh/8fNSH/6c6f7039fe.png
所以,问题是为什么SQL会生成这么糟糕的计划,或者我如何强制EF(6.1)使用不同的计划或接受查询提示。 我对如何解决这个问题提出了任何其他建议。
谢谢!
答案 0 :(得分:3)
如果没有执行计划的完整XML以及相关统计数据,优化器为什么会产生这个或那个计划,这很难做出任何假设。
但是,您还询问了如何强制使用特定计划,为此有答案。
使用计划指南告诉优化程序要做什么。通过特定查询的计划指南,您可以指定某些优化程序提示甚至整个执行计划。如果缓存中有一个好的计划,很容易通过计划指南来修复它。
这在网上书籍中得到了很好的解释:
http://technet.microsoft.com/en-us/library/ms179880.aspx
你也可以打开强制参数化,但要小心这一点并进行彻底的测试,因为它的数据库范围设置会影响每个查询,无论是好还是坏。