一:何为索引
实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。
二:什么情况下使用索引
动作描述 |
使用聚集索引 |
使用非聚集索引 |
列经常被分组排序 |
应 |
应 |
返回某范围内的数据 |
应 |
不应 |
一个或极少不同值 |
不应 |
不应 |
小数目的不同值 |
应 |
不应 |
大数目的不同值 |
不应 |
应 |
频繁更新的列 |
不应 |
应 |
外键列 |
应 |
应 |
主键列 |
应 |
应 |
|
|
|
三:正确认识索引
1.主键就是聚集索引?
如果我们将这个列设为主键,SQL SERVER会将此列默认为聚集索引。这样做有好处,就是可以让您的数据在数据库中按照ID进行物理排序,但笔者认为这样做意义不大。显而易见,聚集索引的优势是很明显的,而每个表中只能有一个聚集索引的规则,这使得聚集索引变得更加珍贵。
(1)仅在主键上建立聚集索引,并且不划分时间段: Select gid,fariqi,neibuyonghu,title from tgongwen
用时:128470毫秒(即:128秒)
(2)在主键上建立聚集索引,在fariq上建立非聚集索引:
select gid,fariqi,neibuyonghu,title from Tgongwen
where fariqi> dateadd(day,-90,getdate())
用时:53763毫秒(54秒)
(3)将聚合索引建立在日期列(fariqi)上:
select gid,fariqi,neibuyonghu,title from Tgongwen
where fariqi> dateadd(day,-90,getdate())
用时:2423毫秒(2秒)
虽然每条语句提取出来的都是25万条数据,各种情况的差异却是巨大的,特别是将聚集索引建立在日期列时的差异。事实上,如果您的数据库真的有 1000万容量的话,把主键建立在ID列上,就像以上的第1、2种情况,在网页上的表现就是超时,根本就无法显示。这也是我摒弃ID列作为聚集索引的一个最重要的因素。得出以上速度的方法是:在各个select语句前加:
declare @d datetime
set @d=getdate()
并在select语句后加:
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
2、只要建立索引就能显著提高查询速度
事实上,我们可以发现上面的例子中,第2、3条语句完全相同,且建立索引的字段也相同;不同的仅是前者在fariqi字段上建立的是非聚合索引,后者在此字段上建立的是聚合索引,但查询速度却有着天壤之别。所以,并非是在任何字段上简单地建立索引就能提高查询速度。
从建表的语句中,我们可以看到这个有着1000万数据的表中fariqi字段有5003个不同记录。在此字段上建立聚合索引是再合适不过了。在现实中,我们每天都会发几个文件,这几个文件的发文日期就相同,这完全符合建立聚集索引要求的:“既不能绝大多数都相同,又不能只有极少数相同”的规则。由此看来,我们建立“适当”的聚合索引对于我们提高查询速度是非常重要的。
3、把所有需要提高查询速度的字段都加进聚集索引,以提高查询速度
上面已经谈到:在进行数据查询时都离不开字段的是“日期”还有用户本身的“用户名”。既然这两个字段都是如此的重要,我们可以把他们合并起来,建立一个复合索引(compound index)。
很多人认为只要把任何字段加进聚集索引,就能提高查询速度,也有人感到迷惑:如果把复合的聚集索引字段分开查询,那么查询速度会减慢吗?带着这个问题,我们来看一下以下的查询速度(结果集都是25万条数据):(日期列fariqi首先排在复合聚集索引的起始列,用户名neibuyonghu排在后列):
(1)select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>''2004-5-5''
查询速度:2513毫秒
(2)select gid,fariqi,neibuyonghu,title from Tgongwen
where fariqi>''2004-5-5'' and neibuyonghu=''办公室''
查询速度:2516毫秒
(3)select gid,fariqi,neibuyonghu,title from Tgongwen where neibuyonghu=''办公室''
查询速度:60280毫秒
从以上试验中,我们可以看到如果仅用聚集索引的起始列作为查询条件和同时用到复合聚集索引的全部列的查询速度是几乎一样的,甚至比用上全部的复合索引列还要略快(在查询结果集数目一样的情况下);而如果仅用复合聚集索引的非起始列作为查询条件的话,这个索引是不起任何作用的。当然,语句1、2 的查询速度一样是因为查询的条目数一样,如果复合索引的所有列都用上,而且查询结果少的话,这样就会形成“索引覆盖”,因而性能可以达到最优。同时,请记住:无论您是否经常使用聚合索引的其他列,但其前导列一定要是使用最频繁的列。
四、其他书上没有的索引使用经验总结
1、用聚合索引比用不是聚合索引的主键速度快
下面是实例语句:(都是提取25万条数据)
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16''
使用时间:3326毫秒
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where gid<=250000
使用时间:4470毫秒
这里,用聚合索引比用不是聚合索引的主键速度快了近1/4。
2、用聚合索引比用一般的主键作order by时速度快,特别是在小数据量情况下
select gid,fariqi,neibuyonghu,reader,title from Tgongwen order by fariqi
用时:12936
select gid,fariqi,neibuyonghu,reader,title from Tgongwen order by gid
用时:18843
这里,用聚合索引比用一般的主键作order by时,速度快了3/10。事实上,如果数据量很小的话,用聚集索引作为排序列要比使用非聚集索引速度快得明显的多;而数据量如果很大的话,如10万以上,则二者的速度差别不明显。
3、使用聚合索引内的时间段,搜索时间会按数据占整个数据表的百分比成比例减少,而无论聚合索引使用了多少个:
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-1-1''
用时:6343毫秒(提取100万条)
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-6-6''
用时:3170毫秒(提取50万条)
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16''
用时:3326毫秒(和上句的结果一模一样。如果采集的数量一样,那么用大于号和等于号是一样的)
select gid,fariqi,neibuyonghu,reader,title from Tgongwen
where fariqi>''2004-1-1'' and fariqi<''2004-6-6''
用时:3280毫秒
4、日期列不会因为有分秒的输入而减慢查询速度
下面的例子中,共有100万条数据,2004年1月1日以后的数据有50万条,但只有两个不同的日期,日期精确到日;之前有数据50万条,有5000个不同的日期,日期精确到秒。
select gid,fariqi,neibuyonghu,reader,title from Tgongwen
where fariqi>''2004-1-1'' order by fariqi
-- 建立测试表
create table t_userinfo
(
userid int identity(1,1) primary key nonclustered,
nick varchar(50) not null default '',
classid int not null default 0,
writetime datetime not null default getdate()
)
go
-------------------------------------------------------------------
-- 建 clustered 聚集索引
create clustered index ix_userinfo_classid on t_userinfo(classid)
go
-------------------------------------------------------------------
-- 插入100万条测试数据
declare @i int
declare @k int
declare @nick varchar(10)
set @i = 1
while @i<1000000
begin
set @k = @i % 10
set @nick = convert(varchar,@i)
insert into t_userinfo(nick,classid,writetime) values(@nick,@k,getdate())
set @i = @i + 1
end
go
-------------------------------------------------------------------
-- 普通 not in 查询 结果:3.5 秒左右
declare @d datetime
set @d=getdate()
-----------------
select top 20 userid,nick,classid,writetime from t_userinfo
where userid not in
(
select top 900000 userid from t_userinfo order by userid asc
)
-----------------
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
-------------------------------------------------------------------
-- 查询 结果:0.4 秒左右
--(普通查询,利用默认的主键userid,速度没有多少提升)
declare @d datetime
set @d=getdate()
-----------------
select a.userid,b.nick,b.classid,b.writetime from
(
select top 20 a.userid from
(
select top 900020 userid from t_userinfo order by userid asc
)
a order by a.userid desc
) a inner join t_userinfo b on a.userid = b.userid
order by a.userid asc
-----------------
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
-------------------------------------------------------------------
-- where 查询 结果:0.5 秒左右
--(利用了classid聚集索引列查询,但只是用于查询top 900000 userid 最后还是where查询,效率较低)
declare @d datetime
set @d=getdate()
-----------------
select top 20 userid,nick,classid,writetime from t_userinfo where classid = 1 and userid not in
(
select top 90000 userid from t_userinfo where classid = 1 order by userid asc
)
-----------------
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
-------------------------------------------------------------------
-- 优化 where 查询 结果:0.1 秒左右
--(效果最好针对classid列有大量重复值,建立聚集索引查询,同时优化查询20userid,再利用where查询,速度很快了就。)
declare @d datetime
set @d=getdate()
-----------------
select a.userid,b.nick,b.classid,b.writetime from
(
select top 20 a.userid from
(
select top 900000 userid from t_userinfo where classid = 1 order by userid asc
)
a order by a.userid desc
)
a inner join t_userinfo b on a.userid = b.userid order by a.userid asc
----------------
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
五、其他注意事项
“水可载舟,亦可覆舟”,索引也一样。索引有助于提高检索性能,但过多或不当的索引也会导致系统低效。因为用户在表中每加进一个索引,数据库就要做更多的工作。过多的索引甚至会导致索引碎片。
所以说,我们要建立一个“适当”的索引体系,特别是对聚合索引的创建,更应精益求精,以使您的数据库能得到高性能的发挥。
当然,在实践中,作为一个尽职的数据库管理员,您还要多测试一些方案,找出哪种方案效率最高、最为有效。
相关推荐
6. **维护和优化**:在SQL Server 2005中,你可以利用新的特性和功能对数据库进行优化,例如使用新的索引策略、调整查询性能等。 在实际操作过程中,可能会遇到各种问题,如兼容性问题、性能瓶颈、数据一致性等。...
- **输入输出参数 (INOUT)**:MS SQL Server 支持使用 `@variable OUTPUT` 定义输入输出参数,而 PostgreSQL 使用 `INOUT` 关键字。 #### 返回结果集的函数 - **MS SQL Server** 支持通过 `SELECT` 语句直接返回...
### MS SQL Server 分区表、分区索引详解 #### 一、分区表简介 使用分区表的主要目的是为了改善大型表及具有多种访问模式的表的可伸缩性和可管理性。这里的“大型表”指的是数据量巨大的表,“访问模式”是指因不同...
除了备份和恢复,Acronis Recovery for MS SQL Server还可能包含安全性功能,如SN(序列号)可能指的是产品激活码,用于验证软件的合法使用。在安装和使用过程中,用户需要输入正确的序列号以激活软件,确保所有功能...
对于使用MS SQL Server的企业和个人来说,了解并掌握查询优化技巧能够显著提升系统的响应速度与整体性能。本文将基于提供的信息,深入探讨MS SQL Server查询优化的关键技术和实践方法。 #### 二、MS SQL Server查询...
String url = "jdbc:sqlserver://localhost:1433;databaseName=myDB"; String username = "myUser"; String password = "myPassword"; try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); ...
索引选择阶段,MS SQL Server优化器选择合适的索引,以提高查询效率。连接选择阶段,MS SQL Server优化器选择合适的连接顺序,以提高查询效率。 查询优化的指导性策略和实用方法 为了提高MS SQL Server数据库的查询...
《基于MS SQL Server的索引研究与应用》这篇文章主要探讨了在Microsoft SQL Server数据库系统中,索引的重要性和使用策略。索引是一种提高数据检索效率的机制,它为数据库表中的数据行创建了一种分散存储的结构,由...
Ms SqlServer是一款广泛应用于企业级数据库管理的系统,由Microsoft公司开发。对于数据库管理员和开发者来说,拥有一个方便好用的客户端管理工具至关重要,能够提高工作效率,简化日常维护任务。标题提到的“方便...
在IT行业中,MS SQL Server是微软公司开发的关系型数据库管理系统,广泛应用于企业级数据存储、管理和分析。本篇文章将深入探讨一些MS SQL Server的关键数据库技巧,帮助你优化工作流程,提高效率。 一、查询优化 ...
3、恢复MS SQL数据库中最重要和最有价值的元素:数据类型,表数据,视图,存储过程,自定义函数,触发器,索引,主键和外键,限制等 4、将数据库恢复为几个文件(* .mdf + * .ndf) 5、在恢复mdf文件期间修复损坏的...
5. **索引**:SQL Server使用索引来加速数据检索,包括B树索引、聚集索引和非聚集索引等。 6. **复制技术**:SQL Server支持数据复制,可以将数据从一个服务器复制到多个服务器,用于分布式系统或灾难恢复。 7. **...
针对文件内容的全文检索,本文介绍了一种利用Windows索引服务和MS SQL Server结合的解决方案,使得用户能够在上传的文件中进行高效、准确的全文搜索。 首先,文件存储策略是关键。为了确保文件的独特性和便于索引,...
此外,用户还可以自定义追踪,选择需要监视的特定事件类别,如锁、死锁、索引使用等。 追踪器的界面设计直观,使用户能够轻松过滤、排序和分析追踪结果。通过查看追踪结果,你可以看到每个SQL语句的执行时间、CPU...
在MS SQLSERVER面试中,涉及的知识点广泛且深入,以下是对题目中提到的一些关键概念的详细解释: 1) **触发器**(Triggers): 触发器是一种特殊类型的存储过程,当数据库中的特定DML操作(INSERT, UPDATE, DELETE)...
《MS SQL Server 7 参考手册 - 编程语言》是针对微软SQL Server 7.0版本的数据库管理系统中编程语言部分的详尽指南。SQL Server 7.0是微软在20世纪末推出的重要数据库产品,它引入了许多新特性和改进,使得数据库...
本文将深入探讨使用MS SQL Server作为后台数据库,配合前端应用程序开发实现企业级进销存管理系统的相关知识。 MS SQL Server是微软公司推出的一款关系型数据库管理系统(RDBMS),它在数据存储、处理和管理方面...
首先,标题中的"sqlserver自动生成sql语句工具"指的是可以分析SQL Server数据库结构和数据,自动生成对应的SQL创建语句的软件。这种工具通常能帮助数据库管理员快速获取数据库的定义,便于备份、迁移或在其他环境中...
此外,熟悉SQL Server的特性和最佳实践也是必不可少的,例如,理解索引优化、事务管理、安全性设置等。 总结来说,msbase.jar、mssqlserver.jar和msutil.jar构成了Java连接SQL Server 2000的关键组件,它们共同提供...
"sqlserver离线安装包" 提供了这样一种解决方案,使得我们可以在无网络的情况下完成 SQL Server 的部署。 离线安装通常涉及到以下几个关键步骤和知识点: 1. **下载完整安装包**: 要进行离线安装,首先你需要在有...