此连接项中的示例代码
显示一个错误
SELECT COUNT(*)
FROM dbo.my_splitter_1('2') L1
INNER JOIN dbo.my_splitter_1('') L2
ON L1.csv_item = L2.csv_item
返回正确的结果。但是以下内容返回的结果不正确(2014年使用新的Cardinality Estimator)
SELECT
(SELECT COUNT(*)
FROM dbo.my_splitter_1('2') L1
INNER JOIN dbo.my_splitter_1('') L2
ON L1.csv_item = L2.csv_item)
因为它错误地将L2的结果加载到公共子表达式假脱机中,然后重播L1结果的结果。
我对为什么两个查询之间的行为差异感到好奇。跟踪标志8675显示工作的一个进入search(0) - transaction processing
而失败的一个进入search(1) - quick plan
。
因此,我认为其他转换规则的可用性是行为差异的背后原因(例如,禁用BuildGbApply或GenGbApplySimple似乎可以解决此问题)。
但是,为什么针对这些非常相似的查询的两个计划会遇到不同的优化阶段?根据我的阅读search (0)
,至少需要三个表,并且在第一个示例中肯定不满足该条件。