此文章主要向大家探讨的是SQL Server索引的具体使用标准(Index Usage Criteria),在实际操作中我们大家为了其更为有效的决定创建哪些合适的SQL Server数据库索引,你必须决定这些索引实际中是否被SQL Server使用过。
如果一个索引不能被有效使用,在修改数据时,那只会浪费空间和增加不必要的负担。
需要记住的主要标准是:如果至少是SQL Server索引的***列没有被包含在一个有效的搜索参数(search argument SARG)或join子句中,那么SQL Server 就不会使用索引进行更有效地书签查找(bookmark lookup)。为创建复合索引,选择列的顺序时牢记住这一点,想想下面的在store表中的索引:
CREATE index nc1_stores on stores (city, state, zip)
下面的每一个查询将会用到索引,因为它们包含了SQL Server索引的***列city,其为一个SARG:
Sql代码

然而,下面的查询不会用到SQL Server索引而进行书签查找,因为它们没指定city列为一个SARG:
引用
注释:
对于前面提到的***两个查询,如果你显示执行计划(execution plan)信息,你可能发现,查询实际上使用了nc1_store索引来检索了结果集(resultset)。如果再仔细看,你会发现查询没有使用索引最有效地方式——它使用了索引扫描(index scan),而不是索引查找(index seek)。
有关查询存取方法(query aceess method)的更多信息,可参见第35章“Understanding Query Optimization”,在该章中将讲述索引查找。
在索引查找(Index seek)中,SQL Server 沿着索引树(index tree)从根级(root level)向下进行索引键值匹配搜索,直到搜索到指定的行,然后使用存储在索引键值中的书签值(bookmark value)直接从数据页中检索匹配的数据行(这个书签值可以是行标识符(RID),或者聚集索引的键值)。
对一个索引扫描(Index scan),SQL Server搜索索引树中所有叶级(leaf level)中的行来进行可能匹配的查找。如果发现满足匹配的行,然后利用书签检索数据行。
尽管两者都使用了索引,从I/O代价角度来讲,索引扫描比SQL Server索引查找的代价要高,但比表扫描(Table scan)要略微要小些。然而,本章学习设计索引的目的是为了使用索引查找,所以当我谈到使用索引时,指的是索引查找。
为了得到可能列的书签查询,你可能想到的一个容易的方法是在表中所有列上都创建索引,这样任何类型的查询都可以使用索引了。这种策略可能在某些支持ad hoc queries(随意的查询)的只读的DSS(决策支持系统)环境下是合适的,但是这样也存在问题,因为仍然会造成有许多索引不被使用。
正如你在本章的Index selection节看到的,不会仅仅因为在某列创建了索引,优化器就总会使用该列的索引,例如,当该列的选择性不够时(not selective enough),就不会使用该列的索引。另外,在一张大表(large table)上创建太多索引会占据数据库中的大量空间,增加了备份的要求时间。前面也提到过,在一个OLTP(在线联机处理)系统上,太多的索引会给数据的插入、修改、删除操作带来大量的额外负担,造成性能上的不利影响。
引用
建议:(每张表4-5个索引)
我曾经常犯的一个设计错误是在OLTP环境下定义了太多的索引。许多情况下,有些索引是冗余的或者是优化器在处理查询时就根本没有考虑。结果,这些索引导致空间的浪费和增加了修改数据时的不必要负担。
在这一点上有一个案例,有个客户在一个表上创建了8个索引,其中4个索引都是在同一列上,该列的键值唯一(unique key),在索引中该列都是***个索引列。对表的查询和修改操作,该列都包含在where 子句中。结果只有4个的其中1个SQL Server索引曾被用到过。
希望在本章结束后,你将会理解为什么所有这些索引不是必须的,并且能重新认识和决定在哪些列上创建索引将会收益,而哪些列上应避免创建索引。
【编辑推荐】
alter index语句如何使用?
alter index常用的语法如下:(1)重建指定索引:ALTER INDEX ind ON TAREBUILD;(2)重建全部索引:ALTER INDEX ALL ON TAREBUILD;(3)禁用索引:ALTER INDEX ALL ON TADISABLE;(再次启用使用REBUILD重建而不是ENABLED)(4)指定参数重建索引:ALTER INDEX ALL ON TAREBUILD WITH(FILLFACTOR=80);(5)指定参数修改索引:ALTER INDEX ALL ON TASET(IGNORE_DUP_KEY = ON);注意:alter index语法,不能用于修改索引定义,如添加或删除列,或更改列的顺序AlterAlter是数据库SQL语言的修改语句,可以用来修改基本表,其一般表示格式为:ALTER TABLE<表名>[改变方式]基本介绍数据库SQL语言的修改语句,可以用来修改基本表,其一般表示格式为:ALTER TABLE<表名>[改变方式]改变方式:· 加一个栏位: ADD 栏位 1 栏位 1 资料种类· 删去一个栏位: DROP 栏位 1· 改变栏位名称: CHANGE 原本栏位名 新栏位名 新栏位名资料种类· 改变栏位的资料种类: MODIFY 栏位 1 新资料种类修改方式由上可以看出,修改基本表提供如下四种修改方式:(1)ADD方式:用于增加新列和完整性约束,列的定义方式同CREARE TABLE语句中的列定义方式相同,其语法格式:ALTER TABLE <表名> ADD <列定义>|<完整性约束>。 由于使用此方式中增加的新列自动填充NULL值,所以不能为增加的新列指定NOT NULL约束。 (2)DROP方式:用于删除指定的完整性约束条件,或删指定的列,其语法格式为:ALTER TABLE<表名> DROP [<完整性约束名>]ALTER TABLE<表名> DROP COLUMN <列名>注释:某些数据库系统不允许这种在数据库表中删除列的方式 (DROP COLUMN <列名>)。 (3)CHANGE方式,用于修改某些列,其语法格式:ALTER TABLE [表名] CHANGE <原列名> TO <新列名><新列的数据类型>(4)MODIFY方式,用于修改某些列的数据类型,其语法格式:ALTER TABLE [表名] MODIFY [列名] [数据类型]
SQL server中 表中如何创建索引?
if exists(select *from where naem = newindex) drop index newindex create index --=================================== 竟然没有悬赏...唉... 那算了吧 我还是都告诉你吧.. 看个示例 自己琢磨去: --============================================== use master go if db_id(Nzhangxu)is not null drop database zhangxu go create database zhangxu sp_helpdb zhangxu use zhangxu go IF EXISTS (SELECT *FROM WHERE NAME = NWORKER) DROP TABLE WORKER GO create table worker (w_id int identity (1000,1) not null,w_name Nvarchar(10) unique,w_age SMALLINT CONSTRAINT CK_W_AGE CHECK(w_age>20 and w_age<150),w_pay money DEFAULT 0,CONSTRAINT PK_W_ID PRIMARY KEY(W_ID) ) SELECT *FROM WORKER--用查询技术查看表信息 sp_help worker--利用存储过程查看表信息 /* 创建简单的非聚集索引 */ USE ZHANGXU GO if exists(select name from where name = NIX_ID_NAME) DROP INDEX IX_ID_NAME on worker go--检查是否存在索引,有则删除索引 create index IX_ID_NAME--创建索引 on worker(w_id,w_name)--在ID NAME 两个字段上创建非聚集索引 drop index _ID_NAME--删除索引 select *from where name = IX_ID_NAME--查看索引 /* 创建唯一非聚集索引 */ USE ZHANGXU GO IF EXISTS(SELECT NAME FROM WHERE NAME = NIX_W_NAME) DROP INDEX IX_W_NAME ON WORKER GO CREATE UNIQUE INDEX IX_W_NAME--唯一非聚集索引 ON WORKER(W_NAME) /* 查看索引T-SQL脚本 */ --IX_W_NAME 唯一 非聚集索引 USE [zhangxu] GO /****** 对象: Index [IX_W_NAME] 脚本日期: 07/29/2007 16:54:53 ******/ CREATE UNIQUE NONCLUSTERED INDEX [IX_W_NAME] ON [dbo].[worker] ([w_name] ASC ) WITH ( SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF ) ON [PRIMARY] --PK_W_ID聚集索引 USE [zhangxu] GO /****** 对象: Index [PK_W_ID] 脚本日期: 07/29/2007 16:56:45 ******/ ALTER TABLE [dbo].[worker] ADD CONSTRAINT [PK_W_ID] PRIMARY KEY CLUSTERED ([w_id] ASC ) WITH ( SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF ) ON [PRIMARY] --UQ_WORKER 唯一,非聚集索引 USE [zhangxu] GO /****** 对象: Index [UQ__worker__F21] 脚本日期: 07/29/2007 16:58:38 ******/ ALTER TABLE [dbo].[worker] ADD UNIQUE NONCLUSTERED ([w_name] ASC ) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF ) ON [PRIMARY] select *from worker insert into worker(w_name,w_age,w_pay) values(王国龙,25,4500)
sql-2000中的索引是什么意思?
可以利用索引快速访问数据库表中的特定信息。 索引是对数据库表中一个或多个列(例如,employee 表的姓氏 (lname) 列)的值进行排序的结构。 如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。 索引提供指针以指向存储在表中指定列的数据值,然后根据指定的排序次序排列这些指针。 数据库使用索引的方式与使用书的目录很相似:通过搜索索引找到特定的值,然后跟随指针到达包含该值的行。 在数据库关系图中,可以为选定的表创建、编辑或删除索引/键属性页中的每个索引类型。 当保存附加在此索引上的表或包含此表的数据库关系图时,索引同时被保存。 有关详细信息,请参见创建索引。 通常情况下,只有当经常查询索引列中的数据时,才需要在表上创建索引。 索引将占用磁盘空间,并且降低添加、删除和更新行的速度。 不过在多数情况下,索引所带来的数据检索速度的优势大大超过它的不足之处。 然而,如果应用程序非常频繁地更新数据,或磁盘空间有限,那么最好限制索引的数量。 1.确定数据表的操作是大量的查询还是大量的增删操作,以此确定使用索引的数目,较多增删操作应严格限制索引数目,如果是较多查询可以适当增加索引数目。 2.尝试建立索引来帮助查询。 检查自己的SQL语句,为在WHERE子句中出现的字段建立索引。 使查询引擎快速的定位到指定条件。 3.尝试建立一些复合索引来进一步提高系统性能(修改复合索引将消耗更多的时间,且占磁盘空间)4.对小型表(记录少)建立索引可能反而影响性能,因为此时对表扫描操作效率更高。 (查询优化器不能智能处理)5.避免对具有较少值的字段建立索引(如性别)6.避免选择具有大型数据类型的列作为索引。
发表评论