也谈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:32
  • 6159

SQL Server执行计划教会我如何创建索引?

因为对索引不是很熟悉,所以测试得到结果没有任何价值,甚至有些误导人,这边说声抱歉,在哪跌倒在哪爬起来。 应用场景 还是用商品表(Product)作为示例,表结构如下: 存在这样一种业务场景:...
  • mikemiller2
  • mikemiller2
  • 2016-03-25 16:47:09
  • 336

SQL Server执行计划 解析

当需要分析某个查询的效能时,最好的方式之一查看这个查询的执行计划。执行计划描述SQL Server查询优化器如何实际运行(或者将会如何运行)一个特定的查询。   查看查询的执行计划有几种不同的方式。它...
  • isoleo
  • isoleo
  • 2014-11-26 14:18:42
  • 2325

[SQL Server 2005/2008]重用执行计划(存储过程性能优化)

语句或存储过程第1次执行时,会生成一个经时“查询优化器”优化后的执行计划,默认情况下,还将会缓存这次的执行计划; 下次执行时将直接使用缓存的执行计划,而且不检查这样做是否合适。...
  • xiaoxu0123
  • xiaoxu0123
  • 2010-06-06 16:14:00
  • 2546

sql server 展示执行计划

SET SHOWPLAN_TEXT ON GO SELECT TOP 1000        [Username]       ,[PasswordHash]       ,[Email]      ...
  • wangyonghua8
  • wangyonghua8
  • 2016-11-18 09:19:22
  • 174

如何看MS SQLSERVER数据库的执行计划

1.输入一个查询语句看看SQL Server是如何显示查询计划的吧。 select v.OrderID, v.CustomerID, v.CustomerName, v.OrderDate, v...
  • luoyanqing119
  • luoyanqing119
  • 2013-11-29 12:09:50
  • 7919

SQL Server 2008 对 T-SQL 语言的增强

 SQL Server 2008 对 T-SQL 语言的增强周融,2007 年 7 月(C) 2001-2007 All Rights Reserved.Microsoft SQL Server 20...
  • lee576
  • lee576
  • 2007-07-04 23:08:00
  • 5464

SQL Server 2008 参数化查询 --可重用的缓存计划

我将讨论如果一个查询可以被参数化,那么SQL Server优化器怎样尝试将其参数化,以及你可以怎样建立你自己的参数化查询. 1.什么是参数化查询? 一个简单理解参数化查询的方式是把它看做只是一个T...
  • leamonjxl
  • leamonjxl
  • 2012-04-11 15:14:28
  • 2197

SQL Server 性能调优 之执行计划(Execution Plan)调优

SQL Server 性能调优 之执行计划(Execution Plan)调优
  • sqlchen
  • sqlchen
  • 2014-06-19 15:53:24
  • 2619

Sql Server的执行计划

如何启动执行计划执行计划结果要看什么Sql Server的五种查询方式查看更具体的执行过程参考资料   前一篇总结了Sql Server Profiler,它主要用来监控数据库,并跟踪生成的...
  • wangzhen209
  • wangzhen209
  • 2016-07-20 17:08:25
  • 616
收藏助手
不良信息举报
您举报文章:也谈SQL Server 2008 处理隐式数据类型转换在执行计划中的增强 (续)
举报原因:
原因补充:

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