您好,欢迎来到思海网络,我们将竭诚为您提供优质的服务! 诚征网络推广 | 网站备案 | 帮助中心 | 软件下载 | 购买流程 | 付款方式 | 联系我们 [ 会员登录/注册 ]
促销推广
客服中心
业务咨询
有事点击这里…  531199185
有事点击这里…  61352289
点击这里给我发消息  81721488
有事点击这里…  376585780
有事点击这里…  872642803
有事点击这里…  459248018
有事点击这里…  61352288
有事点击这里…  380791050
技术支持
有事点击这里…  714236853
有事点击这里…  719304487
有事点击这里…  1208894568
有事点击这里…  61352289
在线客服
有事点击这里…  531199185
有事点击这里…  61352288
有事点击这里…  983054746
有事点击这里…  893984210
当前位置:首页 >> 技术文章 >> 文章浏览
技术文章

SQL Server数据库索引优化

添加时间:2014-3-4 16:55:59  添加: 思海网络 

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

  1)对什么列建索引

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

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

  2)一定要在主键上建聚集索引吗

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

  3)复合索引(索引有两个以上的列)要注意列顺序

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

  可以用下面的sql做实验:

  01 USE [Test]
  02 GO
  03 /****** 对象: Table [dbo].[testIndexOrder] 脚本日期: 05/27/2010 09: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/2010 09: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运行一段时间之后就会形成一些索引碎片,这时候就需要重建索引了,有时候重建索引可以起到意想不到的效果。

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

      1 --显示表testIndexOrder的索引碎片情况
  2 DBCC SHOWCONTIG(testIndexOrder)
  3
  4 --重建表的索引
  5 --第一个参数,可以是表名,也可以是表ID。
  6 --第二个参数,如果是'',表示影响该表的所有索引。
  7 --第三个参数,填充因子,即索引页的数据填充程度。如果是,表示每一个索引页都全部填满,此时select效率最高,但以后要插入索引时,就得移动后面的所有页,效率很低。如果是,表示使用先前的填充因子值。
  8 DBCC DBREINDEX(testIndexOrder,'',)

  数据库优化是一门复杂的学问,需要不断的学习实践,积累经验。

关键字:SQL Server、数据库索引、优化

分享到:

顶部 】 【 关闭
版权所有:佛山思海电脑网络有限公司 ©1998-2024 All Rights Reserved.
联系电话:(0757)22630313、22633833
中华人民共和国增值电信业务经营许可证: 粤B1.B2-20030321 备案号:粤B2-20030321-1
网站公安备案编号:44060602000007 交互式栏目专项备案编号:200303DD003  
察察 工商 网安 举报有奖  警警  手机打开网站