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

 

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

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

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

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

 本文继续了解索引视图(Indexes View)

关于索引视图的基本概念,可以在MSDN了解:http://msdn.microsoft.com/zh-cn/library/ms188783.aspx

注意:虽然索引视图是在SQL Server 2000中已经加入,但只有SQL Serer 2008的企业版才支持索引视图的匹配。

我们看一个例子:

Create   table  Table1(id  int   primary   key  ,submitdate  datetime ,commment  nvarchar ( 200 ));

Create   table  Table2(id  int   primary   key   identity ,commentid  int  ,product  nvarchar ( 200 ));

insert   into  Table1(id,submitdate,commment)  values ( 1 , ' 2008-01-09 ' , ' downmoon index view ' )

insert   into  Table2
select   1 , ' SQL Server 2008 r2 '

Create   view  dbo.v1  with  schemabinding
as
select  t1.id,t1.submitdate,t1.commment,t2.product  from  dbo.Table1 t1
inner   join  dbo.Table2 t2  on  t1.id = t2.commentid
go

Create   unique   clustered   index  idx1   on  v1(id); 

 对于以下三种查询:
邀月工作室
邀月工作室

 邀月工作室

 以上三种查询的成本其实是一样的,因为在索引视图的匹配得到了相同的结果。

 查询优化器并非匹配所有的视图,我们看一个不匹配的例子:

Create   Table  table3(col1  int   primary   key   identity ,col2  int );
Insert   into  table3
select   10
union   all   select   20
union   all   select   30

Create   view  dbo.v2  with  schemabinding
as
select  t3.col1,t3.col2  From  dbo.table3 t3  where  t3.col2 > 20 ;
go

Create   unique   clustered   index  idx2   on  v2(col1);

select   *   from  dbo.v2  where  col2 = CONVERT ( int , 10 );

对于不匹配的索引视图,SQL Server直接在基表而不在视图中查询。
邀月工作室

 其实这是个0行查询,因为 col2=10 and col2>20这个条件,SQL Server查询优化器根本不会执行。

SQL Server也支持匹配在某些案例下的索引视图,如列和行的子集。

Create   table  basetbl1(col1  int ,cl2  int ,col3  binary ( 4000 ));

 
Create   unique   clustered   index  idx3   on  basetbl1(col1);

set  nocount  on
BEGIN   TransAction ;
Declare   @i   int
set   @i = 0
while   @i < 50000
BEGIN
    
Insert   into  basetbl1(col1,col2)  values ( @i , 50000 - @i );
    
set   @i = @i + 1
END
Commit   Transaction
go

create   view  dbo.v3  with  schemabinding
as
select  col1,col2  From  dbo.basetbl1 t3
go

create   unique   clustered   index  iv3  on  dbo.v3(col2);

邀月工作室
而如果有列的计算,则会添加计算纯量(Scalar)

邀月工作室
别担心,SQL Server在一整套的索引视图支持结构中设置了一些限制,以确保视图能够在适当的时候被创建、匹配、尽可能高效地被更新。
■分区表
当SQL Server的被用于存储越来越多的数据时,大数据库的管理成为DBA们的恶梦。 首先,执行操作(如索引重建等)的时间与数据大小一起增长,甚至会影响系统的可用性。其次,大表的大小使得执行操作变得困难了,因为系统可用的资源(如临时空间、日志空间和物理内存等)是有限的。此时,表和索引分区将会帮你更好地管理大数据库,并使宕机的可能性最低。
关于SQL Server 2008的表分区的界面操作,陈希章有一篇文章,
使用SQL Server 2008提供的表分区向导
另外,MSDN:
http://msdn.microsoft.com/zh-cn/library/ms179854.aspx
http://technet.microsoft.com/zh-cn/library/ms345599.aspx

物理上,分区表和索引其实是存储了行的分数(或分量fraction)的N个表或索引,当这些与他们的非分区的等值相比较时,计划的差异通常是分区案例被请求遍历表或索引的列表以返回所有的行。在SQL Server 2005中,这通过APPLY操作符表示,本质上就是一个嵌套循环连接。在SQL Server 2005表示中,一个分区IDs的特殊表被通过参数传递到一个(遍历每个分区的)连接内部的查询执行组件。这个机制在大多数情况下工作得很好,但在某些重要的场景,这个模型却不适合。例如,在请求的并行查询计划里有一个限制(restriction),即并行表或索引scan内容(多个线程同时从一个表读取行以改善性能)时,不能工作在嵌套内循环连接的内侧,而这在SQL Server 2005装箱前是不可能被修复的。不幸的是,这是SQL Server 2005中表分区的主要案例。而且,APPLY表示选项启用连接协作,即以同一种方式分区的两个表能被高效地连接。这种设计初衷本来很好,但在实际中并不能实现最初所预想的那样。正是因为这个,SQL Server 2008重新定义了分区表的表示。

 SQL Server 2008在大多数情况下通过(与访问分区表或索引的操作符一起)存储分区来表示分区。这可以带来一些改进,比如可以使并行scan能正常地工作。它也移去了一些在查询优化器中的分区或非分区案例之间的差异,这将避免错过最佳的性能优化机会。

我们看一个例子:

Create  partition  function  pf2008(date)  as  range  right   for   values ( ' 2008-10-01 ' , ' 2008-11-01 ' , ' 2008-12-01 ' )
Create  partition scheme ps2008  as  partition pf2008  all   to  ( [ PRIMARY ] )

Create   table  ptnsales(saledate date,salesperson  int ,amount  money on  ps2008(saledate);

insert   into  ptnsales
select   ' 2008-10-20 ' , 1 , 250.00
union   all   select   ' 2008-11-05 ' , 2 , 129.00
union   all   select   ' 2008-12-23 ' , 2 , 98.00
union   all   select   ' 2008-10-3 ' , 1 , 450.00

邀月工作室
 此模型的一个好处是可以跨分区表进行并行查询:

Create  partition  function  pfparallel( int as  range  right   for   values ( 100 , 200 , 300 )
Create  partition scheme psparallel  as  partition pfparallel  all   to  ( [ PRIMARY ] )
go
create   table  testscan(randomnum  int ,value  int ,data  binary ( 3000 ))  on  psparallel(randomnum)
go
set  nocount  on
BEGIN   TransAction ;
Declare   @i   int
set   @i = 0
while   @i < 100000
BEGIN
    
Insert   into  testscan(randomnum,value)  values ( rand () * 400 , @i );
    
set   @i = @i + 1
END
Commit   Transaction

邀月工作室

 分区表未完待续。

 

下文将关注分区表(Partitioned Tables) 和数据仓库(Data Warehousing)

转载于:https://www.cnblogs.com/downmoon/archive/2010/06/24/1763060.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值