我们有一个有趣的问题,我希望有人能帮助解释一下。在高层次上,问题如下:
以下查询快速执行(1 秒):
SELECT SA.*
FROM cg.SEARCHSERVER_ACTYS AS SA
JOIN CONTAINSTABLE(CG.SEARCHSERVER_ACTYS, NOTE, 'reports') AS T1 ON T1.[Key]=SA.UNIQUE_ID
但是如果我们在查询中添加过滤器,则大约需要 2 分钟才能返回:
SELECT SA.*
FROM cg.SEARCHSERVER_ACTYS AS SA
JOIN CONTAINSTABLE(CG.SEARCHSERVER_ACTYS, NOTE, 'reports') AS T1 ON T1.[Key]=SA.UNIQUE_ID
WHERE SA.CHG_DATE>'19 Feb 2010'
查看两个查询的执行计划,我可以看到在第二种情况下,实际行数和估计行数之间存在巨大差异的两个地方是:
1) 对于 FulltextMatch 表值函数,其中估计约为 22,000 行,实际为 2900 万行(然后在连接前过滤到 1670 行)和 2) 对于全文索引上的索引查找,其中估计为 1 行,实际为 13,000 行
作为估计的结果,优化器选择使用嵌套循环连接(因为它假设行数很少),因此该计划效率低下。
我们可以通过 (a) 参数化查询并向查询添加 OPTION (OPTIMIZE FOR UNKNOWN) 或 (b) 通过强制使用 HASH JOIN 来解决该问题。在这两种情况下,查询都会在不到 1 秒的时间内返回,并且估计值看起来很合理。
我的问题真的是'为什么在表现不佳的情况下使用的估计如此不准确,可以做些什么来改进它们'?
此处使用的索引视图上的索引的统计信息是最新的。
非常感谢任何帮助。