我知道我们应该尽可能避免在查询的 where 子句中使用函数,因为该函数将针对每一行运行以返回正确的结果。但是,同样的原则是否适用于 where 子句中的嵌套选择?
例如:
where col1 in (select col2 from table)
与将选择移动到临时表中。
我知道我们应该尽可能避免在查询的 where 子句中使用函数,因为该函数将针对每一行运行以返回正确的结果。但是,同样的原则是否适用于 where 子句中的嵌套选择?
例如:
where col1 in (select col2 from table)
与将选择移动到临时表中。
不,同样的原则不适用于您给出的示例。优化器通常会尝试将针对派生表的谓词类型转换为基于集合的构造,如
JOIN
orAPPLY
。使用 SQL Server 2019 上的 StackOverflow2010 示例数据库,我运行了这两个查询(在创建两个指示的非聚集索引之后):
两个查询在大约相同的时间内完成,具有非常相似的计划(临时表计划有扫描而不是查找,因为查找是临时表插入的一部分)。
非临时表版本的估计稍微好一些,这可能会对更大的数据集产生更大的影响。
作为旁注,在这种情况下,您可以通过添加
OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION'))
. 对于相同的两个查询,估计值从实际值的 10-30 倍变为实际值的 2-3 倍以内。这是因为原始基数估计模型比后来的 CE 的简单“粗略对齐”执行更好的直方图匹配(有关该更改的一些详细信息,请参阅 Paul White 的文章 SQL Server Join Estimation using Histogram Coarse Alignment )。