zoukankan      html  css  js  c++  java
  • 《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 moneyon 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(intas 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)

  • 相关阅读:
    【转】 IntelliJ IDEA 详细图解最常用的配置 ,适合刚刚用的新人
    安装IntelliJ IDEA默认C盘文件过大怎么办
    [linux]netstat命令详解-显示linux中各种网络相关信息
    [linux]free命令详解-显示内存的使用情况
    用什么工具能找出性能瓶颈?
    [linux]iostat命令详解-监视系统输入输出设备和CPU的使用情况
    [linux]vmstat命令详解-显示虚拟内存状态
    好文章列表
    BigDecimal.setScale 处理java小数点
    Mybatis通用分页
  • 原文地址:https://www.cnblogs.com/downmoon/p/1763060.html
Copyright © 2011-2022 走看看