您的位置:首页 > 编程语言 > ASP

Asp.Net网站优化系列 数据库的优化措施 索引优化

2010-05-27 10:13 495 查看
索引的作用就类似于书的目录,书的目录会按照章节的顺序排列,会指想某一张的位置。这样如果在一本数百页的书里面查找某个章节位置的时候,我们就可
以只扫描书的目录,扫描的范围缩小了n倍,查询的效率自然就提高了。另外在sql
server内存够用的情况下索引会被放到内存中,在内存中查找自然又会提高效率;所以我们必须得合理利用索引。

1)对什么列建索引
数据库默认情况下会对主键建聚集索引,除了这个索引之外还需要在哪些列上建索引呢?
这个问题只能具体情况具体分析,要看需要优化的sql语句(通常是查询次数多,查询相应想要高的语句),根据什么列的条件进行查询。

例如:在论坛的数据库中有一张表是帖子回复表,在论坛的应用中用到最多的就是对指定帖子的某一页的回复进行查询,查询回复表的条件是主贴的id;这
时候在主贴字段上建索引就势在必然。

2)一定要在主键上建聚集索引吗
通常情况下sql
server会自动给主键加上聚集索引,但也有一些例外的情况我们需要把聚集索引建在其他列上,例如我们用到了表分区,而分区的字段不是主键,这时候就需
要将聚集索引建在分区的列上。另外如果查询时根据主键查询较少,而根据其他列的查询较频繁,则也可以考虑将聚集索引建在非主键上。单需要注意的是聚集索引
的列必须是不易变的列,如果聚集索引变了一会引起聚集索引内的记录的搬迁,造成页page的分离与碎片;二会引起每一个非聚
集索引被修改,以便于所有相关的非聚集索引的行的索引键的值被纠正。这既浪费时间和空间,也导致需要整理的碎片,增加了不必要的开销(每个列重组聚集
键)。

3)复合索引(索引有两个以上的列)要注意列顺序
索引在数据库中是以二叉树的形式存储的。包含
A,B两个列的索引会首先根据A列建二叉树,A列的叶节点上才会开始根据B列建二叉树。所以包含两个列的索引就需要根据查询条件所在列来决定两个列在索引
中的顺序。

可以用下面的sql做实验:

show
sourceview
sourceprint?
01
USE[Test]
02
GO
03
/******对象:
Table
[dbo].[testIndexOrder]
脚本日期:05/27/201009:11:26******/
04
SET
ANSI_NULLS
ON
05
GO
06
SET
QUOTED_IDENTIFIER
ON
07
GO
08
CREATE
TABLE
[dbo].[testIndexOrder](
09
[ID]
[
int
]
IDENTITY(1,1)
NOT
NULL
,
10
[FirstName][nvarchar](20)
COLLATE
Chinese_PRC_CI_AS
NOT

NULL
,
11
[LastName][nvarchar](20)
COLLATE
Chinese_PRC_CI_AS
NOT

NULL
,
12
[
Desc
]
[nvarchar](400)
COLLATE
Chinese_PRC_CI_AS
NULL
,
13
CONSTRAINT

[PK_testIndexOrder]
PRIMARY
KEY
CLUSTERED
14
(
15
[ID]
ASC
16
)
WITH
(IGNORE_DUP_KEY=
OFF
)
ON
[
PRIMARY
]
17
)
ON
[
PRIMARY
]
18
GO
19
/******对象:
Index
[IX_testIndexOrder]
脚本日期:05/27/201009:11:51******/
20
CREATE
NONCLUSTERED
INDEX

[IX_testIndexOrder]
ON
[dbo].[testIndexOrder]
21
(
22
[FirstName]
ASC
,
23
[LastName]
ASC
24
)
WITH
(SORT_IN_TEMPDB=
OFF
,DROP_EXISTING=
OFF
,
IGNORE_DUP_KEY=
OFF
,ONLINE=
OFF
)
ON
[
PRIMARY
]
25
GO
26
declare
@i
INT
;
27
DECLARE
@random
varchar
(36);
28
set
@i=0;
29
while@i<100000
30
begin
31
set

@random=newid();
32
33
INSERT
INTO
[testIndexOrder]
34
(FirstName,LastName,[
Desc
])
35
VALUES
(
36
substring
(@random,1,8),
substring
(@random,12,8),@random
37
);
38
set

@i=@i+1
39
end
40
41
42
set
statistics
time
on
43
select
*
from
[testIndexOrder]
where

lastname=
'6F-4ECA-'
44
select
*
from
[testIndexOrder]
where

firstname=
'CAABE009'
45
set
statistics
time
off
4)索引的个数问题
索引提高查询效率是以降低更新、插入、删除的速度为代价的。每当索引列发生变化时都
需要对索引数据进行相应的调整。所以一个表上不可以建太多的索引,除非你完全不在乎修改数据的效率。另外sql
server本身会对索引的数量和索引的数据长度有限制,具体请参考

5)在必要时重建索引
Sql
server运行一段时间之后就会形成一些索引碎片,这时候就需要重建索引了,有时候重建索引可以起到意想不到的效果。

查看索引碎片,重建索引,可以通过sqlserver管理器来重建;也可以通过下面的sql语句来实现:

view
sourceprint?
1
--显示表testIndexOrder的索引碎片情况
2
DBCCSHOWCONTIG(testIndexOrder)
3
4
--重建表的索引
5
--第一个参数,可以是表名,也可以是表ID。
6
--第二个参数,如果是'',表示影响该表的所有索引。
7
--第三个参数,填充因子,即索引页的数据填充程度。如果
是,表示每一个索引页都全部填满,此时select效率最高,但以后要插入索引时,就得移动后面的所有页,效率很低。如果是,表示使用先前的填充因子值。
8
DBCCDBREINDEX(testIndexOrder,
''
,)
数据库优化是一门复杂的学问,需要不断的学习实践,积累经验。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: