我在这里需要一些帮助。
我目前正在对一些动态SQL进行故障排除,这需要一个年龄来返回结果。我正在使用SQL Server 2008 R2,构建10.50.4305
我已经执行了SQL跟踪,所以我现在可以看到发生了什么,基本上罪魁祸首是聚簇索引扫描。
选择包含:
WHERE
Name LIKE 'value' + '%' ESCAPE '\'
ORDER BY
这会导致聚簇索引扫描。
如果我将选择更改为
DECLARE @Query nvarchar(50)
SET @Query = 'EIKO'
SET NOCOUNT ON
SELECT TOP 5 pex.Ric.Name AS Id, pex.Ric.Name + '|' + pex.Ric.DisplayName AS Name FROM pex.Ric WITH (nolock) WHERE pex.Ric.Name LIKE @Query + '%' ESCAPE '\' ORDER BY PeId, Name
我得到索引搜索和键查找。
我看起来像使用forceseek查询提示但我收到错误....
Msg 8622,Level 16,State 1,Line 6
由于此查询中定义的提示,查询处理器无法生成查询计划。重新提交查询而不指定任何提示,也不使用SET FORCEPLAN。
非常感谢有关如何在查询中保留参数以及避免聚簇索引扫描的任何帮助或建议。
我已经将查询添加到原始问题中,无论结果是快还是慢,@ Query的值都是相同的
User.findOneAndUpdate(
{ id: req.params.userid },
{ $pull: { 'posts': { 'posts._id': { $eq: req.body.postID } } } },
{ new: true }
)
答案 0 :(得分:2)
正如我的评论中所指出的,我假设,动态SQL中的一些字符被解释为模式。 ESCAPE
的用法可以是一个提示,您知道这一点,并且您插入替换字符以将这些特殊字符标记为 normal ...
看起来好像你只是在寻找同样的开始......试试这个
WHERE LEFT(Name,LEN(@Query))=@Query
这应该从Name
的左侧剪切相同的字符数,并将其与@Query
变量进行比较。
这种方法不会那么快,因为它不是可以攻击的,也不能使用索引,但是 - 如果我的假设是正确的 - 它应该比LIKE
更快,而不是ORDER BY
对每一行进行复杂的模式检查...
可能是,其他沉重的行为窃取了服务器的资源?你试过没有EXEC
吗?
我刚尝试过,我可以重现这一点。搜索文字意味着优化器事先知道所有内容:最佳预测,统计和索引的最佳使用。此外,您的结果可能会产生误导。如果反复执行此操作,结果将被缓存。使用相同的查询,您可能会获得非常快速的答案 - 但它们来自缓存......
参数嗅探也可能是一个问题。
将语句创建为字符串(使用文字)并使用echo
来运行可能会有所帮助。