也谈SQL Server 2008 处理隐式数据类型转换在执行计划中的增强 (续)

原创 2015年07月03日 16:58:57

在上一篇文章也谈SQL Server 2008 处理隐式数据类型转换在执行计划中的增强 中,我提到了隐式数据类型转换增加对于数据分布很不平均的表,评估的数据行数与实际值有很大出入的问题,进一步测试之后,我发现这种评估不准确性应该确实与猜测的一样,它使用了变量的评估方式。通过如下测试验证,首先建立数据分布不平均的测试表。

USE tempdb
GO
CREATE TABLE _t(
    c varchar(50)
);
CREATE INDEX IX_c ON _t( c );
GO

-- 加入 10000 条数据
INSERT _t
SELECT (9999 + id) FROM(
    SELECT TOP 10000 id = ROW_NUMBER() OVER( ORDER BY GETDATE() )
    FROM sys.all_columns a, sys.all_columns
)ID

-- 将 100 - 10000 的数据变成相同值
UPDATE _t SET c = '' WHERE c >= '10100'

然后通过 varhcar和nvarchar值分别测试满足条件1条和满足条件8900条的执行计划预估行数。

ALTER INDEX IX_c ON _t REBUILD;
GO
SET SHOWPLAN_ALL ON
GO
SELECT * FROM _t WHERE c = '10005';     -- 实际1条
GO
SET SHOWPLAN_ALL OFF;
GO

ALTER INDEX IX_c ON _t REBUILD;
GO
SET SHOWPLAN_ALL ON
GO
SELECT * FROM _t WHERE c = N'10005';     -- 实际1条
GO
SET SHOWPLAN_ALL OFF;
GO

ALTER INDEX IX_c ON _t REBUILD;
GO
SET SHOWPLAN_ALL ON
GO
SELECT * FROM _t WHERE c = '';          -- 实际9900条
GO
SET SHOWPLAN_ALL OFF;
GO

ALTER INDEX IX_c ON _t REBUILD;
GO
SET SHOWPLAN_ALL ON
GO
SELECT * FROM _t WHERE c = N'';         -- 实际9900条
GO
SET SHOWPLAN_ALL OFF;
GO

得到的查询计划预估行数如下图所示
这里写图片描述
从图中显示的预估数据行数可以看到,对于varchar值(不需要隐匿的数据类型转换),其预估的结果是准确的。但对于nvarchar值,不管指定的值是只有一条数据,还是有8900条数据匹配,其预估的结果都是99.0099,这说明预估并没有考虑我们指定的值。
进一步用变量测试

ALTER INDEX IX_c ON _t REBUILD;
GO
SET SHOWPLAN_ALL ON
GO
DECLARE @v varchar;SELECT * FROM _t WHERE c = @v; -- varchar
GO
SET SHOWPLAN_ALL OFF;
GO

ALTER INDEX IX_c ON _t REBUILD;
GO
SET SHOWPLAN_ALL ON
GO
DECLARE @nv nvarchar;SELECT * FROM _t WHERE c = @nv; -- nvarchar
GO
SET SHOWPLAN_ALL OFF;
GO

结果如下图所示:
这里写图片描述

不管是varchar,还是nvarchar的变量,预估的行数都是99.0099,这个值与使用nvarchar常量值的结果一样,看来SQL Server查询优化器应该确实把 GetRangeThroughConvert 的结果看成变量了,这个应该是设计上考虑不太周全的地方了,毕竟指定固定常量值的时候,GetRangeThroughConvert的结果应该也是确定值才对。(这个问题在 SQL Server 2014中看起来是调整过来了,在2014中测试没有发现这样的现象)。

相关文章推荐

也谈SQL Server 2008 处理隐式数据类型转换在执行计划中的增强

在 SQL Server 查询中,不经意思的隐匿数据类型转换可能导致极大的查询性能问题,在 SQL Server 2008 及之后的版本中,这种操作做了增强,但还是经常遇到有问题的时候...
  • zjcxc
  • zjcxc
  • 2015年07月02日 17:49
  • 4144

SQL Server 2008的数据类型

SQLServer 2008自带的数据类型及说明 数据类型名称 类别 长度(单位:字节) 数据特点 Bit 整型 ...
  • vjudge
  • vjudge
  • 2014年08月31日 11:37
  • 466

C#中SQL SERVER 2008字符数据类型使用心得

一、尽可能使用Varchar,少使用或者不使用Char字符类型 因为char类型输入的数据长度达不到设计长度,会用空格补足,下面是数据表设计图: 下面是编辑前200行的图:   凡是输入的...

SQL Server 2008中的新日期数据类型

摘要 你是否曾经想在数据库中存储一个日期而没有时间部分,或者想存储一个时间值希望有更高的精度?在SQL Server 2008的介绍中,微软介绍了一些新的日期数据类允许你只存储一个日期、更高精度的时...

SQL Server 2008中的数据类型

SQL Server表中的每一个字段都只能包含一个预先指定的特定数据类型,例如字符或数字。这个声明叫做数据类型。在这篇文章里,我们将比较和对照SQL Server 2008的各种数据类型。此外,我们还...

SQL Server 2008中原生的分层数据类型:hierarchyid

SQL Server 2008中SQL应用系列--目录索引 如果是在SQL 2000中,我们需要读取分层结构数据时,不得不借助递归。在SQL server 2005中,我们可以使用CTE,当然,好的数...

SQL Server 2008之数据类型

数据类型的选择可以帮助优化查询,比如针对int类型列和针对文本类型列可能会生成完全不同的查询计划(效率不同) 三种数据类型: 系统数据类型,别名数据类型:用户可以为系统数据类型提供一个别名,并且可...
  • wide288
  • wide288
  • 2013年07月15日 16:59
  • 569

SQL Server 2008 的数据类型 HierarchyID 的使用

http://www.cftea.com/c/2009/04/GVQCPXGMHTEC3XEM.asp    介绍 我将在本文里向你介绍 SQLServer2008 的一个新特点:Hierarc...
  • zw_2011
  • zw_2011
  • 2012年01月31日 15:01
  • 2023

SQL Server 2008连载之数据类型

SQL Server 2008连载之数据类型

SQL Server 2008空间数据类型

转自:http://www.cnblogs.com/beniao/archive/2011/02/19/1931041.html SQL Server 2008空间数据类型   友情提示,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:也谈SQL Server 2008 处理隐式数据类型转换在执行计划中的增强 (续)
举报原因:
原因补充:

(最多只允许输入30个字)