《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)