《Microsoft Sql server 2008 Internals》读书笔记--第八章The Query Optimizer(5)

 

《Microsoft Sql server 2008 Internals》读书笔记订阅地址:

http://www.cnblogs.com/downmoon/category/230397.html/rss

《Microsoft Sql server 2008 Internals》索引目录:

《Microsoft Sql server 2008 Internal》读书笔记--目录索引

上篇主要列举了统计的概念和统计的设计、统计的浓度。本文将关注筛选统计和字符串统计、基线估计(cardinality estimation)。  

 

■筛选统计

作为SQL Server 2008中新增的筛选索引的一部分,筛选统计功能被加入。这意味着(某个基于筛选谓词的表的行的子集的)统计对象被创建。可以通过sys.stats视图来查看无数据输出。筛选统计可以避免一个常见的问题:即由于数据列与列之间的相关性而变得倾斜(不准确)。比如,我们有一个表cars,一列Make,一列Model。如下记录:

Create   table  Cars
(
Car_ID 
int  ,
Make 
nvarchar ( 20 ),
MODEL 
Nvarchar ( 20 )
);
truncate   table  cars
 
insert   into  Cars
select   1 , ' Ford ' , ' F-150 '
union   all   select   2 , ' Ford ' , ' Taurus '
union   all   select   3 , ' BMW ' , ' M3 '

假定您想执行如下查询:

select   *   from  cars  where  Make = ' Ford '   and  MODEL = ' F-150 '  

查询处理器试图作选择时,它假定每一个AND子句的条件是相互独立的,实际上执行的结果是各条件的乘积,即(1/3)*(2/3)=2/9。然而真实的结果应该是1/3,因为F-150肯定是Ford。当数据量很大时,这个误差是惊人的。

筛选统计通过捕捉一个带条件的可能性从Model列进行筛选,筛选条件为Make列为Ford,这在大多数情况下会修正统计中的运算错误,特别是在where 子句包含一个相对较小的惟一值时非常有效。

除了假定独立性外,查询优化器还采用其他假定来简化估算进程。另外两个假定是统一性假定和包含性假定。没有这些假定,许多常见的查询将会变得性能寒碜。

■字符串统计

SQL Server 2005采取了一项新内容来改善针对字符串的基线估计,叫做字符串统计或Trie Trees,SQL Server直方图的上限是200步(或200个惟一值),来存放整个表的分发信息。特别在查询中使用like时,两百个惟一值不足以提供(针对字符串的)精准的基线估计,而在表外存储大量的字符串会占用大量的空间。Trie Tree此时可以用来在列中高效地存储一些样例字符串。

Trie Trees没有公开,但它通常的结构类似于如下:
如果一个列包含如下值:
ABC

AAA

ABCDEF

ADAD

BBB
对应的tier Tree如下:
邀月工作室

 SQL Server实际上在列中存储了一个字符串的样例。这提供了一种存储远超过200的惟一子字符串的频度信息的能力。

 ■基线估计细节

在优化期间,查询里的每一个运算符被计算以评估该操作影响的行数,这有助于查询优化器基于不同的查询计划作出正确的权衡。这个过程是自下而上的。基表基线和统计被用于输入到其上的树节点。我们看一个例子:

Create   table  Table2010_3(col1  int ,col2  int ,col3  int );
go
set  nocount  on
BEGIN   TransAction ;
Declare   @i   int
set   @i = 0
while   @i < 10000
BEGIN
    
Insert   into  Table2010_3(col1,col2,col3)  values ( @i , @i , @i % 50 );
    
set   @i = @i + 1
END
Commit   Transaction
go
Create   statistics  s2010_3  on  Table2010_3(col3);
go
select  col1,col2  from  Table2010_3  where  col3 < 10

其逻辑查询树如下:
邀月工作室
对于该查询,Filter操作请求在每一个参与谓词的列(本例中是col3)上进行统计,该请求被传承到Table2010_3,适当的统计对象被创建或更新的地方。统计对象此时被传递到筛选器,以决定操作的选择性。选择性被用于从样例延展评估。

一旦一个操作的可选择性被计算,它与当前查询的当前行数相乘。

看下图:
邀月工作室

 因为0-49中有10个是小于10的,即10/50=0.2

10000*0.2=2000行。

我们来验证一下,
邀月工作室

本例中,存储在直方图中的浓度信息为0.02

又如下列查询:

 select COUNT(*from Table2010_3 group by col3

邀月工作室

评估的行数为(1/0.02)*(10000/10000)=50

当一个多列统计对象被创建时,它按照统计对象的顺序为这些被计算的列集计算浓度信息。我们再看下例:

Create   table  Table2010_4(col1  int ,col2  int ,col3  int );
go
set  nocount  on
BEGIN   TransAction ;
Declare   @i   int
set   @i = 0
while   @i < 10000
BEGIN
    
Insert   into  Table2010_4(col1,col2,col3)  values ( @i % 5 , @i % 10 , @i % 50 );
    
set   @i = @i + 1
END
Commit   Transaction
go

邀月工作室

如果前两个列是随机数,则浓度信息可能类似下图:
邀月工作室

这解释了每个col1,col2,col3的组合实际上是惟一的。通过检查进入基线估计进程的各种各样的输入(Input),判断计划在编译期间有无使用合理的信息成为可能。

本文主要介绍了筛选统计和字符串统计、基线估计,下文将关注Limitation和Costing

 

转载于:https://www.cnblogs.com/downmoon/archive/2010/06/20/1752715.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值