当前位置:文档之家› SQL 索引详解

SQL 索引详解

SQL 索引详解
SQL 索引详解

SQL 索引详解

什么是索引

拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K 。为了加快查找的速度,汉语字(词)典一般都有按拼音、笔画、偏旁部首等排序的目录(索引),我们可以选择按拼音或笔画查找方式,快速查找到需要的字(词)。

同理,SQL Server允许用户在表中创建索引,指定按某列预先排序,从而大大提高查询速度。

? SQL Server中的数据也是按页( 4KB )存放

?索引:是SQL Server编排数据的内部方法。它为SQL Server提供一种方法来编排查询数据。

?索引页:数据库中存储索引的数据页;索引页类似于汉语字(词)典中按拼音或笔画排序的目录页。

?索引的作用:通过使用索引,可以大大提高数据库的检索速度,改善数据库性能。

索引类型

?唯一索引:唯一索引不允许两行具有相同的索引值

?主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。

主键索引要求主键中的每个值是唯一的,并且不能为空

?聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个

?非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个

索引类型:再次用汉语字典打比方,希望大家能够明白聚集索引和非聚集索引这两个概念。

唯一索引:

唯一索引不允许两行具有相同的索引值。

如果现有数据中存在重复的键值,则大多数数据库都不允许将新创建的唯一索引与表一起保存。当新数据将使表中的键值重复时,数据库也拒绝接受此数据。例如,如果在stuInfo表中的学员员身份证号(stuID) 列上创建了唯一索引,则所有学员的身份证号不能重复。

提示:创建了唯一约束,将自动创建唯一索引。尽管唯一索引有助于找到信息,但为了获得最佳性能,建议使用主键约束或唯一约束。

主键索引:

在数据库关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。当在查询中使用主键索引时,它还允许快速访问数据。

聚集索引(clustered index)

在聚集索引中,表中各行的物理顺序与键值的逻辑(索引)顺序相同。表只能包含一个聚集索引。例如:汉语字(词)典默认按拼音排序编排字典中的每页页码。拼音字母a,b,c,d……x,y,z就是索引的逻辑顺序,而页码1,2,3……就是物理顺序。默认按拼音排序的字典,其索引顺序和逻辑顺序是一致的。即拼音顺序较后的字(词)对应的页码也较大。如拼音“ha”对应的字(词)页码就比拼音“ba” 对应的字(词)页码靠后。

非聚集索引(Non-clustered)

如果不是聚集索引,表中各行的物理顺序与键值的逻辑顺序不匹配。聚集索引比非聚集索引(nonclustered index)有更快的数据访问速度。例如,按笔画排序的索引就是非聚集索引,“1”画的字(词)对应的页码可能比“3”画的字(词)对应的页码大(靠后)。

提示:SQL Server中,一个表只能创建1个聚集索引,多个非聚集索引。设置某列为主键,该列就默认为聚集索引

如何创建索引

使用T-SQL语句创建索引的语法:

CREATE [UNIQUE] [CLUSTERED|NONCLUSTERED]

INDEX index_name

ON table_name (column_name…)

[WITH FILLFACTOR=x]

q UNIQUE表示唯一索引,可选

q CLUSTERED、NONCLUSTERED表示聚集索引还是非聚集索引,可选

q FILLFACTOR表示填充因子,指定一个0到100之间的值,该值指示索引页填满的空间所占的百分比

在stuMarks表的writtenExam列创建索引:

USE stuDB

GO

IF EXISTS (SELECT name FROM sysindexes

WHERE name = 'IX_writtenExam')

DROP INDEX stuMarks.IX_writtenExam

/*--笔试列创建非聚集索引:填充因子为30%--*/

CREATE NONCLUSTERED INDEX IX_writtenExam

ON stuMarks(writtenExam)

WITH FILLFACTOR= 30

GO

/*-----指定按索引 IX_writtenExam 查询----*/

SELECT * FROM stuMarks (INDEX=IX_writtenExam)

WHERE writtenExam BETWEEN 60 AND 90

虽然我们可以指定SQL Server按哪个索引进行数据查询,但一般不需要我们人工指定。SQL Server将会根据我们创建的索引,自动优化查询。

索引的优缺点

?优点

–加快访问速度

–加强行的唯一性

?缺点

–带索引的表在数据库中需要更多的存储空间

–操纵数据的命令需要更长的处理时间,因为它们需要对索引进行更新

创建索引的指导原则

?请按照下列标准选择建立索引的列。

–该列用于频繁搜索

–该列用于对数据进行排序

?请不要使用下面的列创建索引:

–列中仅包含几个不同的值。

–表中仅包含几行。为小型表创建索引可能不太划算,因为SQL Server在索引中搜索数据所花的时间比在表中逐行搜索所花的时间更长

人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS)中表现得尤为明显。笔者在工作实践中发现,不良的SQL往

往来自于不恰当的索引设计、不充份的连接条件和不可优化的where子句。在对它们进行适当的优化后,其运行速度有了明显地提高!下面我将从这三个方面分别进行总结: 为了更直观地说明问题,所有实例中的SQL运行时间均经过测试,不超过1秒的均表示为(< 1秒)。

测试环境--

主机:HP LH II

主频:330MHZ

内存:128兆

操作系统:Operserver5.0.4

数据库:Sybase11.0.3

一、不合理的索引设计

例:表record有620000行,试看在不同的索引下,下面几个SQL的运行情况:

1.在date上建有一非个群集索引

select count(*) from record where date >

'19991201' and date < '19991214'and amount >

2000 (25秒)

select date,sum(amount) from record group by date

(55秒)

select count(*) from record where date >

'19990901' and place in ('BJ','SH') (27秒)

分析:

date上有大量的重复值,在非群集索引下,数据在物理上随机存放在数据页上,在范围查找时,必须执行一次表扫描才能找到这一范围内的全部行。

2.在date上的一个群集索引

select count(*) from record where date >

'19991201' and date < '19991214' and amount >

2000 (14秒)

select date,sum(amount) from record group by date

(28秒)

select count(*) from record where date >

'19990901' and place in ('BJ','SH')(14秒)

分析:

在群集索引下,数据在物理上按顺序在数据页上,重复值也排列在一起,因而在范围查找时,可以先找到这个范围的起末点,且只在这个范围内扫描数据页,避免了大范围扫描,提高了查询速度。

3.在place,date,amount上的组合索引

select count(*) from record where date >

'19991201' and date < '19991214' and amount >

2000 (26秒)

select date,sum(amount) from record group by date

(27秒)

select count(*) from record where date >

'19990901' and place in ('BJ', 'SH')(< 1秒)

分析:

这是一个不很合理的组合索引,因为它的前导列是place,第一和第二条SQL没有引用pl ace,因此也没有利用上索引;第三个SQL使用了place,且引用的所有列都包含在组合索引中,形成了索引覆盖,所以它的速度是非常快的。

4.在date,place,amount上的组合索引

select count(*) from record where date >

'19991201' and date < '19991214' and amount >

2000(< 1秒)

select date,sum(amount) from record group by date

(11秒)

select count(*) from record where date >

'19990901' and place in ('BJ','SH')(< 1秒)

分析:

这是一个合理的组合索引。它将date作为前导列,使每个SQL都可以利用索引,并且在第一和第三个SQL中形成了索引覆盖,因而性能达到了最优。

5.总结:

缺省情况下建立的索引是非群集索引,但有时它并不是最佳的;合理的索引设计要建立在对各种查询的分析和预测上。一般来说:

①.有大量重复值、且经常有范围查询(between, >,< ,>=,< =)和order by、group by发生的列,可考虑建立群集索引;

②.经常同时存取多列,且每列都含有重复值可考虑建立组合索引;

③.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。

二、不充份的连接条件:

例:表card有7896行,在card_no上有一个非聚集索引,表account有191122行,在account_no上有一个非聚集索引,试看在不同的表连接条件下,两个SQL的执行情况:

select sum(a.amount) from account a,

card b where a.card_no = b.card_no(20秒)

将SQL改为:

select sum(a.amount) from account a,

card b where a.card_no = b.card_no and a.

account_no=b.account_no(< 1秒)

分析:

在第一个连接条件下,最佳查询方案是将account作外层表,card作内层表,利用card 上的索引,其I/O次数可由以下公式估算为:外层表account上的22541页+(外层表accoun t的191122行*内层表card上对应外层表第一行所要查找的3页)=595907次I/O 在第二个连接条件下,最佳查询方案是将card作外层表,account作内层表,利用acco unt上的索引,其I/O次数可由以下公式估算为:

外层表card上的1944页+(外层表card的7896行*内层表account上对应外层表每一行所要查找的4页)= 33528次I/O

可见,只有充份的连接条件,真正的最佳方案才会被执行。

总结:

1.多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表;内外表的选择可由公式:外层表中的匹配行数*内层表中每一次查找的次数确定,乘积最小为最佳方案。

2.查看执行方案的方法-- 用set showplanon,打开showplan选项,就可以看到连接顺序、使用何种索引的信息;想看更详细的信息,需用sa角色执行dbcc(3604,310,302)。

三、不可优化的where子句

1.例:下列SQL条件语句中的列都建有恰当的索引,但执行速度却非常慢:

select * from record where

substring(card_no,1,4)='5378'(13秒)

select * from record where

amount/30< 1000(11秒)

select * from record where

convert(char(10),date,112)='19991201'(10秒)

分析:

where子句中对列的任何操作结果都是在SQL运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL 优化器优化,使用索引,避免表搜索,因此将SQL重写成下面这样:

select * from record where card_no like

'5378%'(< 1秒)

select * from record where amount

< 1000*30(< 1秒)

select * from record where date= '1999/12/01'

(< 1秒)

你会发现SQL明显快起来!

2.例:表stuff有200000行,id_no上有非群集索引,请看下面这个SQL:

select count(*) from stuff where id_no in('0','1')

(23秒)

分析:

where条件中的'in'在逻辑上相当于'or',所以语法分析器会将in ('0','1')转化为id_no ='0' or id_no='1'来执行。我们期望它会根据每个or子句分别查找,再将结果相加,这样可以利用id_no上的索引;但实际上(根据showplan),它却采用了"OR策略",即先取出满足每个or子句的行,存入临时数据库的工作表中,再建立唯一索引以去掉重复行,最后从这个临时表中计算结果。因此,实际过程没有利用id_no上索引,并且完成时间还要受tempdb数据库性能的影响。

实践证明,表的行数越多,工作表的性能就越差,当stuff有620000行时,执行时间竟达到220秒!还不如将or子句分开:

select count(*) from stuff where id_no='0'

select count(*) from stuff where id_no='1'

得到两个结果,再作一次加法合算。因为每句都使用了索引,执行时间只有3秒,在620 000行下,时间也只有4秒。或者,用更好的方法,写一个简单的存储过程:

create proc count_stuff as

declare @a int

declare @b int

declare @c int

declare @d char(10)

begin

select @a=count(*) from stuff where id_no='0'

select @b=count(*) from stuff where id_no='1'

end

select @c=@a+@b

select @d=convert(char(10),@c)

print @d

直接算出结果,执行时间同上面一样快!

总结:

可见,所谓优化即where子句利用了索引,不可优化即发生了表扫描或额外开销。

1.任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

2.in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。

3.要善于使用存储过程,它使SQL变得更加灵活和高效。

从以上这些例子可以看出,SQL优化的实质就是在结果正确的前提下,用优化器可以识别的语句,充份利用索引,减少表扫描的I/O次数,尽量避免表搜索的发生。其实SQL的性能优化是一个复杂的过程,上述这些只是在应用层次的一种体现,深入研究还会涉及数据库层的资源配置、网络层的流量控制以及操作系统层的总体设计。

1.合理使用索引

索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如下:

●在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。

●在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。

●在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。

●如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。

●使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量数据后,删除并重建索引可以提高查询速度。

2.避免或简化排序

应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生输出时,优化器就避免了排序的步骤。以下是一些影响因素:

●索引中不包括一个或几个待排序的列;

●group by或order by子句中列的次序与索引的次序不一样;

●排序的列来自不同的表。

为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等。

3.消除对大型表行数据的顺序存取

在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在“学号”这个连接字段上建立索引。

还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where 子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作:

SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR

order_num=1008

虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:

SELECT * FROM orders WHERE customer_num=104 AND order_num>1001

UNION

SELECT * FROM orders WHERE order_num=1008

这样就能利用索引路径处理查询。

4.避免相关子查询

一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。

5.避免困难的正规表达式

MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”

即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM custo mer WHERE zipcode >“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。

另外,还要避免非开始的子串。例如语句:SELECT * FROM customer WHERE zipco de[2,3] >“80”,在where子句中采用了非开始子串,因而这个语句也不会使用索引。

6.使用临时表加速查询

把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:

SELECT https://www.doczj.com/doc/2516476013.html,,rcvbles.balance,……other columns

FROM cust,rcvbles

WHERE cust.customer_id = rcvlbes.customer_id

AND rcvblls.balance>0

AND cust.postcode>“98000”

ORDER BY https://www.doczj.com/doc/2516476013.html,

如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:

SELECT https://www.doczj.com/doc/2516476013.html,,rcvbles.balance,……other columns

FROM cust,rcvbles

WHERE cust.customer_id = rcvlbes.customer_id

AND rcvblls.balance>0

ORDER BY https://www.doczj.com/doc/2516476013.html,

INTO TEMP cust_with_balance

然后以下面的方式在临时表中查询:

SELECT * FROM cust_with_balance

WHERE postcode>“98000”

临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。

注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。

7.用排序来取代非顺序存取

非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动。SQL语句隐藏了这一情况,使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询。

有些时候,用数据库的排序能力来替代非顺序的存取能改进查询。

总结:

可见,所谓优化即where子句利用了索引,不可优化即发生了表扫描或额外开销。

1.任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

2.in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。

3.要善于使用存储过程,它使SQL变得更加灵活和高效。

从以上这些例子可以看出,SQL优化的实质就是在结果正确的前提下,用优化器可以识别的语句,充份利用索引,减少表扫描的I/O次数,尽量避免表搜索的发生。其实SQL的性能优化是一个复杂的过程,上述这些只是在应用层次的一种体现,深入研究还会涉及数据库层的资源配置、网络层的流量控制以及操作系统层的总体设计。

1.合理使用索引

索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如下:

●在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。

●在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。

●在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。

●如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。

●使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量数据后,删除并重建索引可以提高查询速度。

2.避免或简化排序

应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生输出时,优化器就避免了排序的步骤。以下是一些影响因素:

●索引中不包括一个或几个待排序的列;

●group by或order by子句中列的次序与索引的次序不一样;

●排序的列来自不同的表。

为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等。

3.消除对大型表行数据的顺序存取

在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在“学号”这个连接字段上建立索引。

还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where 子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作:

SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR

order_num=1008

虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:

SELECT * FROM orders WHERE customer_num=104 AND order_num>1001

UNION

SELECT * FROM orders WHERE order_num=1008

这样就能利用索引路径处理查询。

4.避免相关子查询

一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。

5.避免困难的正规表达式

MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”

即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。

另外,还要避免非开始的子串。例如语句:SELECT * FROM customer WHERE zipco de[2,3] >“80”,在where子句中采用了非开始子串,因而这个语句也不会使用索引。

6.使用临时表加速查询

把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:

SELECT https://www.doczj.com/doc/2516476013.html,,rcvbles.balance,……other columns

FROM cust,rcvbles

WHERE cust.customer_id = rcvlbes.customer_id

AND rcvblls.balance>0

AND cust.postcode>“98000”

ORDER BY https://www.doczj.com/doc/2516476013.html,

如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:

SELECT https://www.doczj.com/doc/2516476013.html,,rcvbles.balance,……other columns

FROM cust,rcvbles

WHERE cust.customer_id = rcvlbes.customer_id

AND rcvblls.balance>0

ORDER BY https://www.doczj.com/doc/2516476013.html,

INTO TEMP cust_with_balance

然后以下面的方式在临时表中查询:

SELECT * FROM cust_with_balance

WHERE postcode>“98000”

临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。

注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。

7.用排序来取代非顺序存取

非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动。SQL语句隐藏了这一情况,使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询。

有些时候,用数据库的排序能力来替代非顺序的存取能改进查询。

当索引键列用户SQL语句的where子句中时,该索引将直接指向包含这些值的行的位置。合理使用索引是减少磁盘I/O的主要方法,不管索引是否存在,都无需修改任何SQL语句的定义。索引只是一种加快数据访问的途径,它只影响执行速度。

索引可以加快数据的访问速度,也可以加快数据的查询速度,oracle中的索引大致分为一下几种:

1、唯一索引:唯一索引是唯一的,也可以是非唯一的。唯一索引可以确保在定义索引的列中,表的任意两行的值都不相同。非唯一索引没有在列上规定此限制。oracle自动为表的主键列创建唯一索引。可以使用create unique index命令明确的创建唯一索引;

Sql代码

1.create unique index item_index on tableName(columnname);

2、组合索引:组合索引是在表中的多个列上创建的索引。组合索引中的列的顺寻是任意的,不必是表中相邻的列,如过select语句中的where子句引用的组合索引中的所有列或大多数列,则组合索引可以提高数据的检索速度。创建组合索引时,应该注意定义中使用的列的顺序。通常,最频繁访问的列应放置在列表的最前面。

Sql代码

1.create index comp_index on tablename(a_column,b_column);

3、反向键索引:他是一种特殊类型的索引,在索引基于有序数的列时非常有用。因此,反向键索引通常建立在一些值连续增长的列上(高基数字段)

Sql代码

1.create index rev_index on table(columnname) reverse;

2.--使用noreverse可以将反向键索引重建为标准索引

3.alert index rev_index rebuild noreverse;

4、位图索引:位图索引适用于低基数列,也就是说不同值的数目比表的行数少的列,如果某个列的值重复了超过一百次,则可以考虑在该列上创建位图索引。位图索引的优点:

1、对于大批量的查询,可减少相应的时间;

2、相比其他索引技术,占用空间明显减少;

3、即使在配置很低的终端硬件上,也能获得显著的性能;

Sql代码

1.create bitmap index bit_index on tablename(columnName);

什么时候加索引, 如何加?

最经典的说法: 数据库慢了, 加索引. 加索引就快了吗?它可能使数据库更慢! 再复杂点,对同一字段, 加bitmap index可能快, 加成b-tree就可能更慢.

我觉得什么时候加和如何加应该一起考虑的, 以整体性能的变化为判断依据, 某种方式的索引, 加在某个字段上能够引起整体性能变好时加. 加索引没有绝对化的公式, 有的话数据库就自己替你加了. 加索引是一个尝试-->失败-->再尝试的过程, 直至达到预期的目标(优化前要先定下目标,不过这目标可能永远达不到).DBA完成这一过程所需的时间取决于经验.

加索引的步骤:

1.提取一条SQL作为关键SQL, 尝试加索引(组)以提升性能

2.提取数条关键SQL作为关键SQL组, 验证1得到的索引(组)对关键SQL组的性能影响(Plan 变化), 正面进行3, 负面返回1

3.扩展关键SQL到全体SQL, 验证1得到的索引(组)对全体SQL的性能影响(Plan 变

化), 正面进行4, 负面返回1

4.纪录该索引(组)和它的性能, 不满意或资源足够返回1, 否则进行5

5.对得到的一批索引(组)进行比较, 选取性能最好的.

1可能永远到不了2或5,这时候要进行调整.

加索引要有索引组的概念, 几个索引之间会互相影响的.

简单开个头

建立索引(BTree)首要条件,表记录不能太小(尤其是没有join的表):

1:记录的选择性比较高(不同值不是太少)

2:做表连接的字段

3:经常位于where条件中的字段

……

关于索引可能带来不良影响:

在对大表进行较多记录的范围查询的时候

3个因素会影响数据缓冲区:

(关于2,我实在忘了出处了,sorry。大家可探讨。这关系到缓冲区数据块高低端和级别问题)

1:通过ROWID(索引)读出来的数据,将会挂在数据缓冲区高端,也就是将比较长的时间保持于数据缓冲区,如果重复利用机会小,则将可能造成性能问题

2:由于数据缓冲区的数据替换策略并不是严格的将整个对象替换出去

在压力比较大的情况下,它采取的是压缩各对象数据,换句话说,很可能存在这么一种情况,由于某个对象数据的进入,假设同时换出了5个对象的10%的数据,而以后正好又查询需要用这5个对象的被换出部分数据,则……

3: 索引本身也会占用sga,当索引大到一定程度的时候也需要考虑这个问题

当然,oracle采取这种策略也是有它的道理的

上面说的这些情况,毕竟不是常见的,只是一种可能

怎样才能充分利用SQL索引

怎样才能充分利用SQL索引 背景:目前WEB的普及太快,很多网站都会因为大流量的数据而发生服务器习惯性死机,一个查询语句只能适用于一定的网络环境.没有优化的查询当遇上大数据量时就不适用了. 本文主旨:讨论什么情况下能利用上索引. 索引:创建索引可以根据查询业务的不同分为两种:单一列的索引,联合索引. 顾名思义,单一列索引就是指在表的某一列上创建索引,联合索引是在多个列上联合创建索引. 优缺点比较: 1):索引所占用空间:单一列索引相对要小. 2):索引创建时间:单一列索引相对短. 3):索引对insert,update,delete的影响程序:单一列索引要相对低. 4):在多条件查询时,联合索引效率要高. 索引的使用范围:单一列索引可以出现在where 条件中的任何位置,而联合索引需要按一定的顺序来写. 本文所用测试软件环境如下:SQL05 DEMO:创建一个人员表,包含人员ID,姓名.在人员ID上创建一个聚集索引,在first_name和last_name上创建一个联合 索引. create table person (id int, last_name varchar(30), first_name varchar(30)) create unique clustered index person_id on person (id) create index person_name on person (last_name, first_name) 在上例中,id上创建了聚集索引,下面的查询都会用了聚集索引. where id=1 where id>1

where id<1 where id between 1 and n where id like '1%' where id in(1,2,3...) 说明: id 列出现在条件中的位置并不一定要求第一列,不受位置影响. 不过下面的查询方式则不会用上聚集索引. where person_id +1=n where person_id like '%5' where person_id like '%5%' where person_id abs(15) 联合索引列比起单一列索引最大的好处在于,对于多条件的查询它比起单一列索引更加精确.拿上面的人员表来说吧,如果 要查询一个人的全名,只知道first_name是很难马上找到这个人的全名的,如果知道first_name和last_name则会非常容易找到.下面根据不同的条件与输出列顺序说明索引的应用. 第一种情况:--条件和输出列和索引列顺序相同 select last_name,first_name from person where last_name='1' and first_name='1' stmtText Index Seek(OBJECT:([bdg_web_vaction].[dbo].[person].[person_name]), SEEK:([bdg_web_vaction].[dbo].[person].[last_name]=[@1] AND [bdg_web_vaction].[dbo].[person].[first_name]=[@2]) ORDERED FORWARD) 结果:利用person_name联合索引查找 第二种情况:--条件列与索引列顺序不同,但输出列相同 select last_name,first_name from person where first_name='1' and

sql索引类型

sql索引类型 唯一索引:唯一索引不允许两行具有相同的索引值 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空 聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个 优点 加快访问速度 加强行的唯一性 缺点 带索引的表在数据库中需要更多的存储空间 操纵数据的命令需要更长的处理时间,因为它们需要对索引进行更新 请按照下列标准选择建立索引的列。 该列用于频繁搜索 该列用于对数据进行排序 一、索引的概念 索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。 二、索引的特点 1.索引可以加快数据库的检索速度 2.索引降低了数据库插入、修改、删除等维护任务的速度 3.索引创建在表上,不能创建在视图上 4.索引既可以直接创建,也可以间接创建 5.可以在优化隐藏中,使用索引 6.使用查询处理器执行SQL语句,在一个表上,一次只能使用一个索引 7.其他

三、索引的优点 1.创建唯一性索引,保证数据库表中每一行数据的唯一性 2.大大加快数据的检索速度,这也是创建索引的最主要的原因 3.加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 4.在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 5.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。 四、索引的缺点 1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加 2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大 3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度 五、索引分类 1.直接创建索引和间接创建索引 直接创建索引: CREATE INDEX mycolumn_index ON mytable (myclumn) 间接创建索引:定义主键约束或者唯一性键约束,可以间接创建索引 2.普通索引和唯一性索引 普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn) 唯一性索引:保证在索引列中的全部数据是唯一的,对聚簇索引和非聚簇索引都可以使用 CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn) 3.单个索引和复合索引 单个索引:即非复合索引 复合索引:又叫组合索引,在索引建立语句中同时包含多个字段名,最多16个字段 CREATE INDEX name_index ON username(firstname,lastname) 4.聚簇索引和非聚簇索引(聚集索引,群集索引) 聚簇索引:物理索引,与基表的物理顺序相同,数据值的顺序总是按照顺序排列 CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH ALLOW_DUP_ROW(允许有重复记录的聚簇索引) 非聚簇索引:CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) 六、索引的使用

SQL 索引详解

SQL 索引详解 什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K 。为了加快查找的速度,汉语字(词)典一般都有按拼音、笔画、偏旁部首等排序的目录(索引),我们可以选择按拼音或笔画查找方式,快速查找到需要的字(词)。 同理,SQL Server允许用户在表中创建索引,指定按某列预先排序,从而大大提高查询速度。 ? SQL Server中的数据也是按页( 4KB )存放 ?索引:是SQL Server编排数据的内部方法。它为SQL Server提供一种方法来编排查询数据。 ?索引页:数据库中存储索引的数据页;索引页类似于汉语字(词)典中按拼音或笔画排序的目录页。 ?索引的作用:通过使用索引,可以大大提高数据库的检索速度,改善数据库性能。 索引类型 ?唯一索引:唯一索引不允许两行具有相同的索引值 ?主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。 主键索引要求主键中的每个值是唯一的,并且不能为空 ?聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个 ?非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个 索引类型:再次用汉语字典打比方,希望大家能够明白聚集索引和非聚集索引这两个概念。 唯一索引: 唯一索引不允许两行具有相同的索引值。 如果现有数据中存在重复的键值,则大多数数据库都不允许将新创建的唯一索引与表一起保存。当新数据将使表中的键值重复时,数据库也拒绝接受此数据。例如,如果在stuInfo表中的学员员身份证号(stuID) 列上创建了唯一索引,则所有学员的身份证号不能重复。 提示:创建了唯一约束,将自动创建唯一索引。尽管唯一索引有助于找到信息,但为了获得最佳性能,建议使用主键约束或唯一约束。 主键索引: 在数据库关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。当在查询中使用主键索引时,它还允许快速访问数据。

SQL中的索引

SQL中的索引分为两种,一种为聚集索引和非聚集索引,下面介绍两者的异同。 聚集索引与非聚集索引: 1、聚集索引: 聚集索引的意思可以理解为顺序排列,比如一个主键自增的表即为聚集索引,即id为1的存在于第一条,id为2的存在于第二条...假使数据库中是使用数组来存放的这张表中的数据,那么如果我需要查找第100条,那么直接第一条数据的地址加上100即为第一百条的地址,一次就能查询出来。 因为数据库中的数据只能按照一个顺序进行排列,所以聚集索引一个数据库只能有一个。在mysql中,不能自己创建聚集索引,主键即为聚集索引,如果没有创建主键,那么默认非空的列为聚集索引,如果没有非空的列那么会自动生成一个隐藏列为聚集索引。 所以一般在mysql中,我们创建的主键即为聚集索引,数据是按照我们的主键顺序进行排列。所以在根据主键进行查询时会非常快。 2、非聚集索引: 非聚集索引可以简单理解为有序目录,是一种以空间换取时间的方法。举个例子,在一个user表中,有一个id_num,即身份号,此不为主键id,那么这些数据在存储的时候都是无序的,比如 id为1的id_num为100,id为2的id_num为97,id为3的id_num为98,id 为4的id_num为99,id为5的id_num为96。。。id为67的id_num为56。。。 那么如果我要查找id_num为56的人,那么只能一条一条的遍历,n条就需要查询n次,时间复杂度为O(n),这是非常耗费性能的。 所以,现在就需要为id_num增加非聚集索引,添加了非聚集索引后,会给id_num 进行排序(内部使用结构为B+树),并且排序后,我只需要查询此目录(即查询B+树),很快就知道为id为56的在数据库中的第67条,而不需要在去遍历表中的所有数据。 所以,在非聚集索引中,不重复的数据越多,那么索引的效率越高。 索引的操作: 我们平常在数据库中使用的索引一般非聚集索引,下面介绍其使用方法: 1、创建索引: 1.1、创建普通索引: 模式: CREATE INDEX 索引名 ON 表名(列名1,列名2,...); 或者 修改表: ALTER TABLE 表名ADD INDEX 索引名 (列名1,列名2,...); 或者 创建表时指定索引:CREATE TABLE 表名 ( [...], INDEX 索引名 (列名1,列名2,...) );

SQL索引详解(优化数据库)

SQL索引一步到位 SQL索引在数据库优化中占有一个非常大的比例,一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开他的神秘面纱。 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书馆那么多书,怎么管理呢?建立一个字母开头的目录,例如:a开头的书,在第一排,b开头的在第二排,这样在找什么书就好说了,这个就是一个聚集索引,可是很多人借书找某某作者的,不知道书名怎么办?图书管理员在写一个目录,某某作者的书分别在第几排,第几排,这就是一个非聚集索引 字典的例子:字典前面的目录,可以按照拼音和部首去查询,我们想查询一个字,只需要根据拼音或者部首去查询,就可以快速的定位到这个汉字了,这个就是索引的好处,拼音查询法就是聚集索引,部首查询就是一个非聚集索引. 看了上面的例子,下面的一句话大家就很容易理解了:聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。就像字段,聚集索引是连续的,a后面肯定是b,非聚集索引就不连续了,就像图书馆的某个作者的书,有可能在第1个货架上和第10个货架上。还有一个小知识点就是:聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。 1.2 索引的存储机制 首先,无索引的表,查询时,是按照顺序存续的方法扫描每个记录来查找符合条件的记录,这样效率十分低下,举个例子,如果我们将字典的汉字随即打乱,没有前面的按照拼 音或者部首查询,那么我们想找一个字,按照顺序的方式去一页页的找,这样效率有多底,大家可以想象。 聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致,其实理解起来非常简单,还是举字典的例子:如果按照拼音查询,那么都是从a-z的,是 具有连续性的,a后面就是b,b后面就是c,聚集索引就是这样的,他是和表的物理排列顺序是一样的,例如有id为聚集索引,那么1后面肯定是2,2后面肯定是3,所以说这样的搜索顺序的就是聚集索引。非聚集索引就和按照部首查询是一样是,可能按照偏房查询的时候,根据偏旁‘弓’字旁,索引出两个汉字,张和弘,但是这两个其实一个在100页,一个在1000页,(这里只是举个例子),他们的索引顺序和数据库表的排列顺序是不一样的,这个样的就是非聚集索引。 原理明白了,那他们是怎么存储的呢?在这里简单的说一下,聚集索引就是在数据库 被开辟一个物理空间存放他的排列的值,例如1-100,所以当插入数据时,他会重新排列 整个整个物理空间,而非聚集索引其实可以看作是一个含有聚集索引的表,他只仅包含原表中非聚集索引的列和指向实际物理表的指针。他只记录一个指针,其实就有点和堆栈差不多的感觉了

SQL Server索引设计和调优技巧大全

SQL Server索引设计与调优

SQL Server索引技巧设计与调优 如果你想极大提高SQL Server性能,本篇指南中提到的索引将是您最佳选择之一。在本文指南中你将了解如何设计最佳SQL Server索引、如何调整SQL Server索引等一系列内容,让你现存的SQL Server索引能够发挥最佳效能。 SQL Server索引设计 SQL Server集簇索引的设计 SQL Server中集群索引设计对SQL Server数据库系统性能和未来的维护十分重要。在本文中你将了解到为什么集群索引应该是静态、随着时间推移而增长、了解它们是如何使用多对多表的。此外,在文中你还会知道在SQL Server 2005中分区表概念是怎样影响集群索引的。 设计SQL Server集簇索引以提升性能(一) 设计SQL Server集簇索引以提升性能(二) 如何创建SQL Server索引 索引的作用应该是确保主要性能。本节你将会学到如何清除那些没有价值的索引并识别推荐索引保证你的SQL Server索引能发挥它的最大效能。 SQL Server索引创建技巧(上) SQL Server索引创建技巧(下) 如何优化索引

索引SQL Server数据库既是艺术也是技术。我们必须根据设计和编码来选择正确的索引。但是,当测试索引设计时,我们可能发现它对系统性能的提高并没有达到我们的要求。我们必须通过学习索引字段、聚簇索引、主键以及索引配置来创建最佳设计的SQL Server索引。文中介绍了一些设计索引时的常见问题。 专家详解SQL Server 2000创建和优化索引 索引的能与不能 在这一系列的问题和答案中,我们将了解索引列和数据库的正确含义,避免出现页面拆分的情况并了解SQL Server 2000的能与不能。 SQL Server 2000索引的能与不能(DO和DON’T) 改进性能的分区索引 SQL Server 2005索引分区允许你将特定索引符合分散到多个文件。本文中还介绍了如何用分区数据创建索引的方法。 改进SQL Server 2005性能的分区索引(上) 改进SQL Server 2005性能的分区索引(下) 聚簇索引和非聚簇索引的区别 什么时候使用聚簇索引或非聚簇索引呢?回答这个问题有点难度,坦白地说,我即将给出的答案是一个流传已久的标准数据库管理员的回答:“具体问题具体分析”。有大量因素影响何时以及何地进行索引创建。幸好只有两个选择,但分析这两个选择的优缺点都相当复杂。

数据库建立索引的原则

数据库建立索引的原则 使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构,例如employee 表的姓(lname)列。如果要按姓查找特定职员,与必须搜索表中的所有行相比,索引会帮助您更快地获得该信息。 索引是一个单独的、物理的数据库结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。 索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引的方式与您使用书籍中的索引的方式很相似:它搜索索引以找到特定值,然后顺指针找到包含该值的行。 在数据库关系图中,您可以在选定表的“索引/键”属性页中创建、编辑或删除每个索引类型。当保存索引所附加到的表,或保存该表所在的关系图时,索引将保存在数据库中。 建立索引的优点 1.大大加快数据的检索速度; 2.创建唯一性索引,保证数据库表中每一行数据的唯一性; 3.加速表和表之间的连接; 4.在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。 索引的缺点 1.索引需要占物理空间。 2.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。 根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。有关数据库所支持的索引功能的详细信息,请参见数据库文档。 提示尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键或唯一约束。有关这些约束的更多信息,请参见主键约束和唯一约束。 唯一索引

唯一索引是不允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee 表中职员的姓(lname) 上创建了唯一索引,则任何两个员工都不能同姓。 有关唯一索引的更多信息,请参见创建唯一索引。 主键索引 数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。有关主键的更多信息,请参见定义主键。 聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。 如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。 一、索引 1. 概念:索引是揭示文献内容出处,提供文献查考线索的工具书。 2. 类型:种类很多,从不同的角度可以划分出不同的类型。按文种分,可以分为中文索引的外文索引;按收录范围分,可以分为综合性索引和专题性索引;按收录文献的时间分,可以分为近期索引和回溯性索引;按索引款目的标目分,可以分为题名索引、著者索引、语词索引、主题索引、分类索引等。 3. 功能:揭示文献的内容和指引读者查找信息 4. 作用:索引揭示了一书、一刊的基本情况,如篇目、文句。可以深入、完整、详细、系统地为读者提所需文献的具体线索。 铁律一:天下没有免费的午餐,使用索引是需要付出代价的。 索引的优点有目共睹,但是,却很少有人关心过采用索引所需要付出的成本。若数据库管理员能够对索引所需要付出的代价有一个充分的认识,也就不会那么随意到处建立索引了。

SQL 创建索引的作用以及如何创建索引

SQL 创建索引的作用以及如何创建索引 SQL 创建索引的作用 一、使用索引的优点: 1、通过唯一性索引(unique)可确保数据的唯一性 2、加快数据的检索速度 3、加快表之间的连接 4、减少分组和排序时间 5、使用优化隐藏器提高系统性能 二、使用索引的原则: 1、在需要经常搜索的列上创建索引 2、主键上创建索引 3、经常用于连接的列上创建索引 4、经常需要根据范围进行搜索的列上创建索引 5、经常需要排序的列上创建索引 6、经常用于where子句的列上创建索引 三、不创建索引的原则: 1、查询很少使用和参考的列不建索引 2、对只有少数值的列不建索引 3、定义为text、image、bit的列不建索引 4、当需要update性能远远高于select性能时不应建索引 四、常用的命令: 1、sp_helpindex :报告表或视图上的索引信息 2、dbcc showcontig :显示指定表的数据和索引的碎片信息 3、dbcc dbreindex :重建指定数据库中一个或多个索引 4、dbcc indexdefrag :整理指定表或视图的聚集索引或辅助索引的碎片 五、优化索引: 1、重建索引(dbcc dbreindex) 2、索引优化向导 3、整理指定的表或视图的聚集索引和辅助索引碎片(dbcc indexefrag) 如何创建索引 CREATE INDEX 语句用于在表中创建索引。 在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。索引 您可以在表中创建索引,以便更加快速高效地查询数据。

用户无法看到索引,它们只能被用来加速搜索/查询。 注释:更新一个包含索引的表需要比更新一个没有索引的表更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。 SQL CREATE INDEX 语法 在表上创建一个简单的索引。允许使用重复的值: CREATE INDEX index_name ON table_name (column_name) 注释:"column_name" 规定需要索引的列。 SQL CREATE UNIQUE INDEX 语法 在表上创建一个唯一的索引。唯一的索引意味着两个行不能拥有相同的索引值。CREATE UNIQUE INDEX index_name ON table_name (column_name) CREATE INDEX 实例 本例会创建一个简单的索引,名为"PersonIndex",在Person 表的LastName 列: CREATE INDEX PersonIndex ON Person (LastName) 如果您希望以降序索引某个列中的值,您可以在列名称之后添加保留字DESC: CREATE INDEX PersonIndex ON Person (LastName DESC) 假如您希望索引不止一个列,您可以在括号中列出这些列的名称,用逗号隔开:CREATE INDEX PersonIndex ON Person (LastName, FirstName)

数据库索引的作用及实例

1.1.索引作用 2.在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的 快速定位技术,能够大大提高查询效率。特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万倍。 3. 4.例如,有3个未索引的表t1、t2、t3,分别只包含列c1、c2、c3,每 个表分别含有1000行数据组成,指为1~1000的数值,查找对应值相等行的查询如下所示。 5. 6.SELECT c1,c2,c3 FROM t1,t2,t3 WHERE c1=c2 AND c1=c3 7. 8.此查询结果应该为1000行,每行包含3个相等的值。在无索引的情况 下处理此查询,必须寻找3个表所有的组合,以便得出与WHERE子句相配的那些行。而可能的组合数目为1000×1000×1000(十亿),显然查询将会非常慢。 9. 10. 如果对每个表进行索引,就能极大地加速查询进程。利用索引的查询 处理如下。 11. 12.(1)从表t1中选择第一行,查看此行所包含的数据。 13. 14.(2)使用表t2上的索引,直接定位t2中与t1的值匹配的行。类似,利 用表t3上的索引,直接定位t3中与来自t1的值匹配的行。 15. 16.(3)扫描表t1的下一行并重复前面的过程,直到遍历t1中所有的行。 17. 18. 在此情形下,仍然对表t1执行了一个完全扫描,但能够在表t2和t3 上进行索引查找直接取出这些表中的行,比未用索引时要快一百万倍。 19. 20. 利用索引,MySQL加速了WHERE子句满足条件行的搜索,而在多表连 接查询时,在执行连接时加快了与其他表中的行匹配的速度。 21. 22.2. 创建索引 23.在执行CREATE TABLE语句时可以创建索引,也可以单独用CREATE INDEX 或ALTER TABLE来为表增加索引。 24. 25.1.ALTER TABLE 26.ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。 27. 28. 29. 30.ALTER TABLE table_name ADD INDEX index_name (column_list) 31. 32.ALTER TABLE table_name ADD UNIQUE (column_list)

数据库建索引及用法

SQL> CREATE TABLE test_tab ( 2 id INT, 3 name V ARCHAR(10), 4 age INT, 5 val V ARCHAR(10) 6 ); 你的业务,有一个查询,是 SELECT * FROM test_tab WHERE name = 一个外部输入的数据 刚开始,数据不多的时候,执行效果还不错。 随着数据量的增加,这个查询,执行起来,越来越慢了。 然后在name 上面建立了索引 CREATE INDEX idx_test4_name ON test_tab (name ); 这样,可以加快前面那个查询的速度。 但是,某天,你执行了下面这个SQL,发现速度又慢了 SELECT * FROM test_tab WHERE age = 25 为啥呢?因为age 字段上面,没有索引 索引只在name 上面有 换句话说,也就是WHERE 里面的条件,会自动判断,有没有可用的索引,如果有,该不该用。 多列索引,就是一个索引,包含了2个字段。 例如: CREATE INDEX idx_test_name_age ON test_tab (name, age); 那么 SELECT * FROM test_tab WHERE name LIKE '张%' AND age = 25 这样的查询,将能够使用上面的索引。 多列索引,还有一个可用的情况就是,某些情况下,可能查询,只访问索引就足够了,不需要再访问表了。例如: SELECT AVG( avg ) AS 平均年龄 FROM

test_tab WHERE name LIKE '张%' 这个时候,name 与age 都包含在索引里面。查询不需要去检索表中的数据。

SQL Server索引基础知识

SQL Server 索引基础知识
SQL Server 索引基础知识 索引基础知识(1)-记录数据的基本格式 记录数据的基本格式
不论是缓存的数据信息,还是物理保存的信息,他们的基本单位都是数据页。所以理解 数据页是最最基础的知识点,本文就介绍跟索引有关的数据页的一些基础知识。
数据页的基础知识
SQL Server 中数据存储的基本单位是页(Page)。数据库中的数据文件(.mdf 或 .ndf)分配的磁盘空间可以从逻辑上划分成页(从 0 到 n 连续编号)。 磁盘 I/O 操作在 页级执行。也就是说,SQL Server 每次读取或写入数据的最少数据单位是数据页。
注意:日志文件不是用这种方式存储的,而是一系列日志记录。
数据库被分成逻辑页面(每个页面 8KB), 并且在每个文件中, 所有页面都被连续地从 0 到 x 编号, 其中 x 是由文件的大小决定的。 我们可以通过指定一个数据库 ID、 一个文件 ID、 一个页码来引用任何一个数据页。 当我们使用 ALTER DATABASE 命令来扩大一个文件时, 新的空间会被加到文件的末尾。 也就是说, 我们所扩大文件的新空间第一个数据页的页码是 x+1。当我们使用 DBCC SHRINKDATABASE 或 DBCC SHRINKFILE 命令来收缩一个 数据库时,将会从数据库中页码最高的页面(文件末尾)开始移除页面,并向页码较低的页面 移动。这保证了一个文件中的页码总是连续的。
在 SQL Server 中,页的大小为 8 KB。这意味着 SQL Server 数据库中每 MB 有 128 页。依次类推。根据数据库的文件大小,我们可以算出数据库有多少数据页。
SQL Server 2005 有以下几种页类型: 有以下几种页类型:
页类型 Data
内容 当 text in row 设置为 ON 时,包含除 text、 ntext、image、

SQl 索引使用教程

SQL Server 索引结构及其使用(一) 作者:freedk 一、深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。下面,我们举例来说明一下聚集索引和非聚集索引的区别: 其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。 如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。 通过以上例子,我们可以理解到什么是“聚集索引”和“非聚集索引”。进一步引申一下,我们可以很容易的理解:每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。 二、何时使用聚集索引或非聚集索引 下面的表总结了何时使用聚集索引或非聚集索引(很重要):

索引SQL语句优化★★★

标题 : 基于索引的SQL语句优化之降龙十八掌 第一掌避免对列的操作 3 第二掌避免不必要的类型转换 4 第三掌增加查询的范围限制 4 第四掌尽量去掉"IN"、"OR" 4 第五掌尽量去掉 "<>" 5 第六掌去掉Where子句中的IS NULL和IS NOT NULL 5 第七掌索引提高数据分布不均匀时查询效率 5 第八掌利用HINT强制指定索引 6 第九掌屏蔽无用索引 6 第十掌分解复杂查询,用常量代替变量 7 第十一掌 like子句尽量前端匹配 7 第十二掌用Case语句合并多重扫描 7 第十三掌使用nls_date_format 8 第十四掌使用基于函数的索引 8 第十五掌基于函数的索引要求等式匹配 9 第十六掌使用分区索引 9 第十七掌使用位图索引 9 第十八掌决定使用全表扫描还是使用索引 9 1 前言 客服业务受到SQL语句的影响非常大,在规模比较大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急剧下降,小型机idle所剩无几,应用服务器断连、超时,严重影响业务的正常运行。因此,称低效的SQL语句为客服业务的‘恶龙’并不过分。数据库的优化方法有很多种,在应用层来说,主要是基于索引的优化。本次秘笈根据实际的工作经验,在研发原来已有的方法的基础上,进行了一些扩充,总结了基于索引的SQL语句优化的降龙十八掌,希望有一天你能用其中一掌来驯服客服业务中横行的‘恶龙’。 2 总纲 l 建立必要的索引 这次传授的降龙十八掌,总纲只有一句话:建立必要的索引,这就是后面降龙十八掌的内功基础。这一点看似容易实际却很难。难就难在如何判断哪些索引是必要的,哪些又是不必要的。判断的最终标准是看这些索引是否对我们的数据库性能有所帮助。具体到方法上,就必须熟悉数据库应用程序中的所有SQL语句,从中统计出常用的可能对性能有影响的部分SQL,分析、归纳出作为Where条件子句的字段及其组合方式;在这一基础上可以初步判断出哪些表的哪些字段应该建立索引。其次,必须熟悉应用程序。必须了解哪些表是数据操作频繁的表;哪些表经常与其他表进行连接;哪些表中的数据量可能很大;对于数据量大的表,其中各个字段的数据分布情况如何;等等。对于满足以上条件的这些表,必须重点关注,因为在这些表上的索引,将对SQL语句的性能产生举足轻重的影响。不过下面还是总结了一下降龙十八掌内功的入门基础,建立索引常用的规则如下: 1、表的主键、外键必须有索引; 2、数据量超过300的表应该有索引; 3、经常与其他表进行连接的表,在连接字段上应该建立索引;

SQL Server数据库中索引使用和优化

SQL Server数据库中索引使用和优化 在应用系统中,尤其在联机事务处理系统中,对数据查询及处理速度已成为衡量应用系统成 Server采用基于代价的优化模型,它对每一个提交的有关表的查询,决定是否使用索引或 标是避免全表扫描,因为全表扫描需要从磁盘上读表的每一个数据页,如果有索引指向数据值,则查询只需读几次磁盘就可以了。所以如果建立了合理的索引,优化器就能利用索引加速数据的查询过程。但是,索引并不总是提高系统的性能,在增、删、改操作中索引的存在会增加一定的工作量,因此,在适当的地方增加适当的索引并从不合理的地方删除次优的索引,将有助于优化那些性能较差的SQL Server应用。实践表明,合理的索引设计是建立在对各种查询的分析和预测上的,只有正确地使索引与程序结合起来,才能产生最佳 一、聚簇索引(clustered indexes)的使用 聚簇索引是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。由于聚簇索引的索引页面指针指向数据页面,所以使用聚簇索引查找数据几乎总是比使用非聚簇索引快。每张表只能建一个聚簇索引,并且建聚簇索引需要至少相当该表 120%的附加空间,以存放该表的副本和索引中间页。建立聚簇索引的思想是: 1、大多数表都应该有聚簇索引或使用分区来降低对表尾页的竞争,在一个高事务的环境中,对最后一页的封锁严重影响系统的吞吐量。 2、在聚簇索引下,数据在物理上按顺序排在数据页上,重复值也排在一起,因而在那些包含范围检查(between、<、<=、>、>=)或使用group by或order by的查询时,一旦找到具有范围中第一个键值的行,具有后续索引值的行保证物理上毗连在一起而不必进一步搜索,避免了大范围扫描,可以大大提高查询速度。 3、在一个频繁发生插入操作的表上建立聚簇索引时,不要建在具有单调上升值的列(如IDENTITY)上,否则会经常引起封锁冲突。 4、在聚簇索引中不要包含经常修改的列,因为码值修改后,数据行必须移动到新的位置。 5、选择聚簇索引应基于where子句和连接操作的类型。 聚簇索引的侯选列是:

SQLServer索引结构及其使用(一)

SQLServer索引结构及其使用(一) 一、深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。下面,我们举例来说明一下聚集索引和非聚集索引的区别:其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。 如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。 通过以上例子,我们可以理解到什么是“聚集索引”和“非聚集索引”。进一步引申一下,我们可以很容易的理解:每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。 二、何时使用聚集索引或非聚集索引

SQL如何建索引

“SQL基础”向你初步介绍了SQL。你学会了如何用SELEC T语句进行查询,你还学会了如何建立自己的表。在这一章里,你将加深你的SQL知识。你将学习如何建立索引来加快查询速度。你还将学会如果用更多的SQL语句和函数来操作表中的数据。 假设你想找到本书中的某一个句子。你可以一页一页地逐页搜索,但这会花很多时间。而通过使用本书的索引,你可以很快地找到你要搜索的主题。 表的索引与附在一本书后面的索引非常相似。它可以极大地提高查询的速度。对一个较大的表来说,通过加索引,一个通常要花费几个小时来完成的查询只要几分钟就可以完成。因此没有理由对需要频繁查询的表增加索引。 当你的内存容量或硬盘空间不足时,也许你不想给一个表增加索引。对于包含索引的数据库,SQL Sever需要一个可观的额外空间。例如,要建立一个聚簇索引,需要大约1.2倍于数据大小的空间。要看一看一个表的索引在数据库中所占的空间大小,你可以使用系统存储过程sp_spaceused,对象名指定为被索引的表名。 聚簇索引和非聚簇索引 假设你已经通过本书的索引找到了一个句子所在的页码。一旦已经知道了页码后,你很可能漫无目的翻寻这本书,直至找到正确的页码。通过随机的翻寻,你最终可以到达正确的页码。但是,有一种找到页码的更有效的方法。 首先,把书翻到大概一半的地方,如果要找的页码比半本书处的页码小,就书翻到四分之一处,否则,就把书翻到四分之三的地方。通过这种方法,你可以继续把书分成更小的部分,直至找到正确的页码附近。这是找到书页的非常有效的一种方法。 SQL Sever的表索引以类似的方式工作。一个表索引由一组页组成,这些页构成了一个树形结构。根页通过指向另外两个页,把一个表的记录从逻辑上分成和两个部分。而根页所指向的两个页又分别把记录分割成更小的部分。每个页都把记录分成更小的分割,直至到达叶级页。 索引有两种类型:聚簇索引和非聚簇索引。在聚簇索引中,索引树的叶级页包含实际的数据:记录的索引顺序与物理顺序相同。在非聚簇索引中,叶级页指向表中的记录:记录的物理顺序与逻辑顺序没有必然的联系。 聚簇索引非常象目录表,目录表的顺序与实际的页码顺序是一致的。非聚簇索引则更象书的标准索引表,索引表中的顺序通常与实际的页码顺序是不一致的。一本书也许有多个索引。例如,它也许同时有主题索引和作者索引。同样,一个表可以有多个非聚簇索引。 通常情况下,你使用的是聚簇索引,但是你应该对两种类型索引的优缺点都有所理解。 每个表只能有一个聚簇索引,因为一个表中的记录只能以一种物理顺序存放。通常你要对一个表按照标识字段建立聚簇索引。但是,你也可以对其它类型的字段建立聚簇索引,如字符型,数值型和日期时间型字段。

数据库索引 index 介绍

数据库索引index 介绍 2010-05-04 对数据库索引的关注从未淡出我的们的讨论,那么数据库索引是什么样的?聚集索引与非聚集索引有什么不同?希望本文对各位同仁有一定的帮助。有不少存疑的地方,诚心希望各位不吝赐教指正,共同进步。 B-Tree 我们常见的数据库系统,其索引使用的数据结构多是B-Tree或者B+Tree。例如,MsSql使用的是B+Tree,Oracle及Sysbase使用的是B-Tree。所以在最开始,简单地介绍一下B-Tree。 B-Tree不同于Binary Tree(二叉树,最多有两个子树),一棵M阶的B-Tree满足以下条件:另外,对于一个结点,其内部的关键字是从小到大排序的。以下是B-Tree(M=4)的样例: 对于每个结点,主要包含一个关键字数组Key[],一个指针数组(指向儿子)Son[]。在B-Tree内,查找的流程是:使用顺序查找(数组长度较短时)或折半查找方法查找Key[]数组,若找到关键字K,则返回该结点的地址及K在Key[]中的位置;否则,可确定K在某个Key[i]和Key[i+1]之间,则从Son[i]

所指的子结点继续查找,直到在某结点中查找成功;或直至找到叶结点且叶结点中的查找仍不成功时,查 找过程失败。 接着,我们使用以下图片演示如何生成B-Tree(M=4,依次插入1~6): 从图可见,当我们插入关键字4时,由于原结点已经满了,故进行分裂,基本按一半的原则进行分裂,然后取出中间的关键字2,升级(这里是成为根结点)。其它的依类推,就是这样一个大概的过程。 数据库索引 在数据库中,索引的含义与日常意义上的“索引”一词并无多大区别(想想小时候查字典),它是用于提高数据库表数据访问速度的数据库对象。 数据页,而不是遍历所有数据页。 。 当然,众所周知,虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引。 一条索引记录中包含的基本信息包括:键值(即你定义索引时指定的所有字段的值)+逻辑指针(指向数据页或者另一索引页)。

相关主题
文本预览
相关文档 最新文档