Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server Unicode转换更改估计行数_Sql Server - Fatal编程技术网

Sql server Unicode转换更改估计行数

Sql server Unicode转换更改估计行数,sql-server,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, Orde

我有一个查询生成了一个错误的执行计划,我跟踪到这样一个事实:执行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)
我将一组测试数据插入表中,然后运行
updatestatistics Orders
<代码>DBCC显示统计信息(订单、主键订单、4F8C6988304CED14)显示此结果:

现在,如果我运行查询

SELECT * FROM Orders WHERE BusinessUnit = 'USA'
其中一个步骤是对订单进行聚集索引搜索,估计行数为735行

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

SELECT * FROM Orders WHERE BusinessUnit = N'USA'
我得到了410.5行的估计数


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

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

当优化器尝试为varchar-varchar查找优化查询时,它使用统计信息来确定最佳查询计划,并估计返回的行数

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


基本上,当比较苹果和橙子并期望匹配时,您可能需要猜测期望的匹配数。

估计值基于所有密度而不是直方图,因为编译时该值未知(由于隐式转换)。0.5乘以821行的所有密度值为410.5。

如果
BusinessUnit
列的类型为
VARCHAR
,那么首先为什么要将其与
NVARCHAR
类型的值进行比较?“非Unicode字段上的索引不能与Unicode子句一起使用吗?”-这取决于排序规则,但即使排序规则允许,您也应该避免这种情况,因为它可能会产生其他影响-正如您所注意到的。出现这种情况是因为实体框架默认进行Unicode转换。我通过使用
IsUnicode(false)
进行列映射解决了这个问题,但我想知道是什么导致了这种行为。@BenRubin,转换不仅会影响行数估计,而且表达式不可搜索,因此无法有效地使用列上的索引(扫描而不是搜索)。对varchar列使用Unicode表达式对性能非常有害。@MartinSmith,没错,我应该在我的评论中说“可能不”而不是“不能”。扫描使用传统SQL排序规则进行,这在美国很常用。