Unicode转换会更改估计的行数

时间:2017-10-06 20:11:02

标签: sql-server

我有一个生成错误执行计划的查询,我追溯到这样一个事实:执行Unicode转换会更改执行计划中的估计行数。

我有这张桌子

CREATE TABLE Orders
(       
    BusinessUnit VARCHAR(5) NOT NULL,
    OrderNumber VARCHAR(10) NOT NULL,
    CustomerId VARCHAR(20)
)

ALTER TABLE Orders ADD PRIMARY KEY(BusinessUnit, OrderNumber)

我在表格中插入了一堆测试数据,然后运行UPDATE STATISTICS OrdersDBCC SHOW_STATISTICS(Orders, PK__Orders__4F8C6988304CED14)向我展示了这个结果:

enter image description here

现在,如果我运行查询

SELECT * FROM Orders WHERE BusinessUnit = 'USA'

其中一个步骤是按订单分组搜索,估计行数为735

但是,如果我添加像这样的Unicode转换

SELECT * FROM Orders WHERE BusinessUnit = N'USA'

我估计行数为410.5。

在进行Unicode转换时,导致估计行数变化的原因是什么?非Unicode字段上的索引是否可以与Unicode子句一起使用?当我有一些连接多个表的较大查询时,在WHERE子句中的单个字段上添加unicode转换会导致查询执行计划发生重大变化,这会使查询的运行时间增加一个数量级

2 个答案:

答案 0 :(得分:1)

在SQL Server中,单个Unicode字符为16位,而非Unicode字符为8位。由于仅为表中的数据类型保留统计信息,因此没有将它们与Unicode值进行比较的良好统计信息。

当优化程序尝试优化varchar< ==>的查询时varchar查找,它使用统计信息来决定最佳查询计划,并估计返回的行数。

但是当它试图根据非varchar值查找varchar数据项时,它必须对不同数据类型如何影响平均查找进行有根据的猜测。我怀疑优化器会直接分析查找字符串中的值以查看当前非Unicode字符集中有多少,因此它可能使用一些预编程的统计值,基于哦,也许是您的默认字符集,也许您的国家/地区代码,用于确定将返回的行数的调整因子。

基本上,在将苹果与橘子进行比较并期待比赛时,您可能需要猜测一下预期的比赛次数。

答案 1 :(得分:1)

估算基于全密度而不是直方图,因为在编译时该值未知(由于隐式转换)。 All Density值为0.521 821行为410.5。