在上一篇文章也谈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 处理隐式数据类型转换在运行计划中的增强 (续)的更多相关文章

  1. SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据

    原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...

  2. SQL Server 2000向SQL Server 2008 R2推送数据

    [文章摘要]最近做的一个项目要获取存在于其他服务器的一些数据,为了安全起见,采用由其他“服务器”向我们服务器推送的方式实现.我们服务器使用的是SQL Server 2008 R2,其他“服务器”使用的 ...

  3. Sql Server函数全解<三>数据类型转换函数和文本图像函数

    阅读目录 一:数据类型转换函数 二:文本和图像函数 一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近的值是有效的,比如int和flo ...

  4. Sql Server函数全解(三)数据类型转换函数和文本图像函数

    一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近的值是有效的,比如int和float,但是对于其它数据类型,例如整型和字符类型,隐士 ...

  5. SQL Server 2008如何导出带数据的脚本文件

    第一步,选中需要导出脚本的数据库,右键选中 第二步,选取弹出菜单中的任务-生成脚本选项(会弹出一SQL生成脚本的向导) 第三步,在向导中点击下一步,弹出选择数据库界面(默认是自己之前选中的数据库),把 ...

  6. SQL Server 2008复制发布订阅(数据同步)

    数据库同步问题 1.有一台主数据库服务器A和另外一台数据库服务器B,客户端首先访问数据库B,当B数据库服务器挂掉时就访问A,当对数据库B进行DML操作时,同时对A进行更新,如果A与B之间通讯失败,则将 ...

  7. SQL Server 2008 R2没有卸载干净

    在卸载Microsoft SQL Server 2008 R2 安装程序(简体中文) 出现 :“警告 26003.无法卸载 Microsoft SQL Server 2008 R2 安装程序支持文件, ...

  8. 【问题&解决】试用版SQL Server 2008 R2 提示评估期已过,数据库不能访问解决办法

    因为以前一直是试用版,重启服务器之后,突然数据库不能访问,提示评估期已过,都快吓死了.还好找到了解决办法特copy解决步骤如下: (笔者用的是企业版: R88PF-GMCFT-KM2KR-4R7GB- ...

  9. SQL Server 2008 R2导出数据脚本的方法

    以前看到有些朋友说必须SQL Server 2008才能导出包含数据的脚本,后来仔细研究发现其实SQL Server 2008 R2也是可以的,只需在导出的时候在高级中设置一下即可. 1.首先在数据库 ...

随机推荐

  1. nodeJS学习(10) --- 事件模块

    转载:http://www.cnblogs.com/zhongweiv/p/nodejs_events.html 目录 简介及资料 事件常用函数及使用 emitter.on(event, listen ...

  2. Intelli IDEA快捷键(配合IdeaVim)

    Intelli IDEA开发环境,个人总结的一些常用的快捷键. 想要使用vim方式编辑代码,可以使用Intelli IDEA的IdeaVim.IdeaVim插件功能很强大,在vim编辑模式下还可以使用 ...

  3. HTML 文档之 Head 最佳实践

    语言 在 html 标签中通过 lang 属性进行明确的语言声明,将会有助于翻译,英文.简体中文和繁体中文网页所属性值如下: <html lang="en"> < ...

  4. pyqt线程实现

    # coding=utf-8 __author__ = 'a359680405' from PyQt5.QtCore import * from PyQt5.QtGui import * from P ...

  5. LeetCode OJ-- Container With Most Water

    https://oj.leetcode.com/problems/container-with-most-water/ 不同高度的柱子排一列,两个柱子可以组成一个容器,求最大容积. 最直观的方法就是暴 ...

  6. Hrbust 2363 Symmys (Manacher + DP)

    题目链接  Hrbust 2363 来源  “科林明伦杯”哈尔滨理工大学第七届程序设计团队赛 Problem J 题意  给出一个长度为$1e6$的字符串,求最小可重回文子串覆盖数量 首先Manach ...

  7. jcraft--SFTP demo

    import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import ...

  8. 串口调试利器--Minicom配置及使用详解

    因为现在电脑基本不配备串行接口,所以,usb转串口成为硬件调试时的必然选择.目前知道的,PL2303的驱动是有的,在dev下的名称是ttyUSB*. Minicom,是Linux下应用比较广泛的串口软 ...

  9. Timeout watchdog using a standby thread

    http://codereview.stackexchange.com/questions/84697/timeout-watchdog-using-a-standby-thread he simpl ...

  10. Http头 Range、Content-Range

    HTTP头中一般断点下载时才用到Range和Content-Range实体头,Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300)Content-Rang ...