SQLServer的复合索引学习
SQLServer创建索引(index)

SQLServer创建索引(index)索引的简介:索引分为聚集索引和⾮聚集索引,数据库中的索引类似于⼀本书的⽬录,在⼀本书中通过⽬录可以快速找到你想要的信息,⽽不需要读完全书。
索引主要⽬的是提⾼了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间。
但是索引对于提⾼查询性能也不是万能的,也不是建⽴越多的索引就越好。
索引建少了,⽤ WHERE ⼦句找数据效率低,不利于查找数据。
索引建多了,不利于新增、修改和删除等操作,因为做这些操作时,SQL SERVER 除了要更新数据表本⾝,还要连带⽴即更新所有的相关索引,⽽且过多的索引也会浪费硬盘空间。
索引的分类:索引就类似于中⽂字典前⾯的⽬录,按照拼⾳或部⾸都可以很快的定位到所要查找的字。
唯⼀索引(UNIQUE):每⼀⾏的索引值都是唯⼀的(创建了唯⼀约束,系统将⾃动创建唯⼀索引)主键索引:当创建表时指定的主键列,会⾃动创建主键索引,并且拥有唯⼀的特性。
聚集索引(CLUSTERED):聚集索引就相当于使⽤字典的拼⾳查找,因为聚集索引存储记录是物理上连续存在的,即拼⾳ a 过了后⾯肯定是 b ⼀样。
⾮聚集索引(NONCLUSTERED):⾮聚集索引就相当于使⽤字典的部⾸查找,⾮聚集索引是逻辑上的连续,物理存储并不连续。
PS:聚集索引⼀个表只能有⼀个,⽽⾮聚集索引⼀个表可以存在多个。
什么情况下使⽤索引:语法:CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_nameON <object> ( column_name [ ASC | DESC ] [ ,...n ] )[ WITH <backward_compatible_index_option> [ ,...n ] ][ ON { filegroup_name | "default" } ]<object> ::={[ database_name. [ owner_name ] . | owner_name. ]table_or_view_name}<backward_compatible_index_option> ::={PAD_INDEX| FILLFACTOR = fillfactor| SORT_IN_TEMPDB| IGNORE_DUP_KEY| STATISTICS_NORECOMPUTE| DROP_EXISTING}参数:UNIQUE:为表或视图创建唯⼀索引。
SQLServer索引中include的魅力(具有包含性列的索引)

SQL Server索引中include的魅力(具有包含性列的索引)
开文之前首先要讲讲几个概念
【覆盖查询】
当索引包含查询引用的所有列时,它通常称为“覆盖查询”。
【索引覆盖】
如果返回的数据列就包含于索引的键值中,或者包含于索引的键值+聚集索引的键值中,那么就不会发生Bookup Lookup,因为找到索引项,就已经找到所需的数据了,没有必要再到数据行去找了。
这种情况,叫做索引覆盖;
【复合索引】
和复合索引相对的就是单一索引了,就是索引只包含一个字段,所以复合索引就是包含两个或者多个字段的索引;
【非键列】
键列就是在索引中所包含的列,当然非键列就是该索引之外的列了;
下面就开始今天的主题
【摘要1】
在SQL Server 2005 中,可以通过将非键列添加到非聚集索引的叶级别来扩展非聚集索引的功能。
通过包含非键列,可以创建覆盖更多查询的非聚集索引。
这是因为非键列具有下列优点:
* 它们可以是不允许作为索引键列的数据类型。
* 在计算索引键列数或索引键大小时,数据库引擎不考虑它们。
当查询中的所有列都作为键列或非键列包含在索引中时,带有包含性非键列的索引可以显著提高查询性能。
这样可以实现性能提升,因为查询优化器可以在索引中找到所有列值;不访问表或聚集索引数据,从而减少磁盘I/O 操作。
说明:第一:只能是针对非聚集索引;第二:比起复合索引是有性能上的提升的,因为索引的大小变小了;
【摘要2】
键列存储在索引的所有级别中,而非键列仅存储在叶级别中。
说明:这就表现为包含与不包含的关系了。
有关索引级别的详细信息,请参阅表组织和索引组织。
SQLServer重建所有表索引

SQLServer重建所有表索引
数据库⼀些数据表数据量剧增之后,⽐如超100W⾏,查询效率会有所降低,就犹如硬盘多了很多碎⽚⼀样。
适当地进⾏表索引重建,可以提升查询效率。
下⾯是对数据库所有表进⾏表索引重建,请在⽆⼈使⽤数据库时使⽤:
DECLARE @TABLE VARCHAR(100)
DECLARE CURT CURSOR FOR SELECT [NAME] FROM SYSOBJECTS WHERE XTYPE='U' ORDER BY ID
OPEN CURT
FETCH NEXT FROM CURT INTO @TABLE
WHILE @@FETCH_STATUS = 0
BEGIN
--参数1是表名。
--参数2指定索引名称,空表所有。
--参数3就填充因⼦,是指索引页的数据填充程度。
--0表⽰使⽤先前的值,100表⽰每个索引页都填满,这时查询效率最⾼,但插⼊索引时会移动其它索引,可根据实际情况来设置。
DBCC DBREINDEX (@TABLE, '', 90)
FETCH NEXT FROM CURT INTO @TABLE
END
CLOSE CURT
DEALLOCATE CURT。
SQLSERVER数据库重建索引的方法

SQLSERVER数据库重建索引的⽅法⼀.查询思路1.想要判断数据库查询缓慢的问题,可以使⽤如下语句,可以列出查询语句的平均时间,总时间,所⽤的CPU时间等信息SELECT creation_time N'语句编译时间',last_execution_time N'上次执⾏时间',total_physical_reads N'物理读取总次数',total_logical_reads/execution_count N'每次逻辑读次数',total_logical_reads N'逻辑读取总次数',total_logical_writes N'逻辑写⼊总次数', execution_count N'执⾏次数', total_worker_time/1000 N'所⽤的CPU总时间ms', total_elapsed_time/1000 N'总花费时间ms', (total_elapsed_time / execution_count)/1000 N'平均时间ms',SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,((CASE statement_end_offsetWHEN -1 THEN DATALENGTH(st.text)ELSE qs.statement_end_offsetEND- qs.statement_start_offset)/2) + 1) N'执⾏语句'FROM sys.dm_exec_query_stats AS qsCROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) stwhere SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,((CASE statement_end_offsetWHEN -1 THEN DATALENGTH(st.text)ELSE qs.statement_end_offsetEND- qs.statement_start_offset)/2) + 1) not like'%fetch%'ORDER BY total_elapsed_time / execution_count DESC;2.列出数据库每个表的数据量,并且需要运维⼈员对业务⾜够了解,知道⼤概哪些表是查询量最多的,可以查看“排在前⾯的表的磁盘使⽤情况”:3.查看表碎⽚的情况,可以使⽤命令DBCC SHOWCONTIG可以看到该表扫描密度只有33.52%(最佳状态是100%,每个表页都写满数据),远远低于最佳计数,也就是说这个表的利⽤率很低,本来扫描⼀页就能出结果,现在可能需要扫描三页,增加了查询时间;⽽逻辑碎⽚和区碎⽚都很多(⼀般认为超过30%就需要优化了),也就是说同样⼀页,数据很少⽽碎⽚很多,占⽤了过多的数据库资源。
SQLServer-索引详细教程(聚集索引,非聚集索引)

SQLServer-索引详细教程(聚集索引,⾮聚集索引)作者:(⼀)必读:深⼊浅出理解索引结构实际上,您可以把索引理解为⼀种特殊的⽬录。
微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和⾮聚集索引(nonclustered index,也称⾮聚类索引、⾮簇集索引)。
下⾯,我们举例来说明⼀下聚集索引和⾮聚集索引的区别:其实,我们的汉语字典的正⽂本⾝就是⼀个聚集索引。
⽐如,我们要查“安”字,就会很⾃然地翻开字典的前⼏页,因为“安”的拼⾳是“an”,⽽按照拼⾳排序汉字的字典是以英⽂字母“a”开头并以“z”结尾的,那么“安”字就⾃然地排在字典的前部。
如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼⾳是“zhang”。
也就是说,字典的正⽂部分本⾝就是⼀个⽬录,您不需要再去查其他⽬录来找到您需要找的内容。
我们把这种正⽂内容本⾝就是⼀种按照⼀定规则排列的⽬录称为“聚集索引”。
如果您认识某个字,您可以快速地从⾃动中查到这个字。
但您也可能会遇到您不认识的字,不知道它的发⾳,这时候,您就不能按照刚才的⽅法找到您要查的字,⽽需要去根据“偏旁部⾸”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。
但您结合“部⾸⽬录”和“检字表”⽽查到的字的排序并不是真正的正⽂的排序⽅法,⽐如您查“张”字,我们可以看到在查部⾸之后的检字表中“张”的页码是672页,检字表中“张”的上⾯是“驰”字,但页码却是63页,“张”的下⾯是“弩”字,页⾯是390页。
很显然,这些字并不是真正的分别位于“张”字的上下⽅,现在您看到的连续的“驰、张、弩”三字实际上就是他们在⾮聚集索引中的排序,是字典正⽂中的字在⾮聚集索引中的映射。
我们可以通过这种⽅式来找到您所需要的字,但它需要两个过程,先找到⽬录中的结果,然后再翻到您所需要的页码。
sql server 中使用 alter index rebuild 语句

sql server 中使用alter index rebuild
语句
在SQL Server 中,ALTER INDEX 语句用于重建、重新组织或重新构建索引。
这有助于解决许多与索引相关的问题,例如碎片化。
以下是使用ALTER INDEX 语句重建索引的基本语法:
SQLALTER INDEX 索引名
ON 表名(列名1, 列名2, ...);
REBUILD;示例:
假设你有一个名为myTable 的表,该表有一个名为myIndex 的索引。
你可以使用以下SQL 语句来重建这个索引:
SQLALTER INDEX myIndex
ON myTable (column1, column2, ...);
REBUILD;参数:
• REBUILD: 这是必需的,它指示SQL Server 应该重新构建而不是重新组织索引。
重新构建索引将删除现有的索引并创建新的索引。
这需要更多的磁盘空间。
• ON: 指定要重建的表的名称。
• (column1, column2, ...): (可选) 在括号中指定要在重建过程中包括的列。
如果不包括任何列,则整个表上的索引将被重建。
注意:
• 在重建索引之前,请确保已经备份了数据库。
• 在生产环境中执行此操作之前,最好在测试环境中进行测试。
• 在高并发的系统中,考虑在低流量时段执行此操作,以最小化对其他查询
和操作的影响。
• 根据你的数据库大小和表大小,这可能需要一段时间来完成。
sql server索引的用法

sql server索引的用法SQL Server索引是一种用于提高查询性能的数据结构。
它可以加速数据的访问速度,减少查询的响应时间。
使用SQL Server索引的主要目的是加快查询操作的速度。
索引可以按照某列或几列的值来排序,这样查询时可以快速定位到需要的数据,而不必扫描整个表。
以下是SQL Server索引的一些常见用法:1. 创建索引:可以通过CREATE INDEX语句在表中创建索引。
可以选择创建唯一索引、聚簇索引、非聚簇索引等不同类型的索引。
2. 删除索引:可以使用DROP INDEX语句删除表中的索引。
删除不再需要的索引可以减少资源的使用和维护成本。
3. 聚簇索引的使用:聚簇索引是按照表的主键创建的一种索引,它决定了表的物理存储顺序。
使用聚簇索引可以提高主键查询的性能。
4. 非聚簇索引的使用:非聚簇索引是按照非主键列的值来创建的索引。
可以根据查询的需要选择适当的列创建索引,以提高查询速度。
5. 覆盖索引的使用:覆盖索引是指包含了查询所需的数据列的索引。
当查询只需要从索引中获取数据时,可以节省I/O操作,提高查询性能。
6. 索引的优化:可以通过查看查询计划和性能监视器等工具,分析索引的使用情况。
根据需要进行索引优化,如添加新索引,删除无用索引,调整索引的顺序等。
7. 统计信息的更新:SQL Server对索引的查询优化依赖于统计信息。
可以使用UPDATE STATISTICS语句更新索引的统计信息,以提高查询计划的准确性。
需要注意的是,索引并不是越多越好,过多的索引可能会增加写操作的开销和存储空间的占用。
在创建索引时需要权衡查询性能和维护成本,并选择合适的索引策略。
sqlserver联合索引规则

sqlserver联合索引规则【实用版】目录1.SQL Server 联合索引的概念和作用2.联合索引的创建方法3.联合索引的使用规则和优化查询性能的方法4.联合索引的注意事项正文一、SQL Server 联合索引的概念和作用联合索引是在 SQL Server 数据库中的一种索引类型,它可以包含两个或多个字段。
联合索引的主要作用是提高查询性能,特别是在涉及到多个字段的查询条件时,可以有效地减少查询时间。
联合索引可以避免数据库进行全表扫描,从而提高查询效率。
二、联合索引的创建方法在 SQL Server 中,创建联合索引的方法如下:1.使用 CREATE INDEX 语句创建联合索引。
例如,创建一个包含 name 和 id 两个字段的联合索引,可以使用以下 SQL 语句:```CREATE INDEX index_nameON table_name(name, id);```2.进入 SQL 企业管理器,右击要创建索引的表,选择“修改”,然后在“表设计器”中选择“索引/键”,点击“添加”按钮。
在弹出的对话框中,可以设置索引名称、类型和包含的字段等属性。
三、联合索引的使用规则和优化查询性能的方法在使用联合索引时,需要注意以下几点规则:1.查询条件中需要使用联合索引的第一个字段作为查询条件,否则联合索引不会被使用。
例如,如果创建了一个包含 name 和 id 的联合索引,那么查询条件中需要使用 name 作为查询条件,否则联合索引不会生效。
2.联合索引的使用可以避免数据库进行全表扫描,从而提高查询效率。
但是,如果查询条件中涉及到的字段不是联合索引的第一个字段,那么联合索引不会被使用。
例如,如果创建了一个包含 name 和 id 的联合索引,但查询条件中只涉及 id 字段,那么联合索引不会被使用。
3.优化查询性能的方法包括:确保查询条件中使用联合索引的第一个字段;避免在查询条件中使用非联合索引字段;尽量减少联合索引中字段的数量,以降低索引维护的开销。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
概要
什么是单一索引,什么又是复合索引呢? 何时新建复合索引,复合索引又需要注意些什么呢?
一.概念
单一索引是指索引列为一列的情况,即新建索引的语句只实施在一列上。
用户可以在多个列上建立索引,这种索引叫做复合索引(组合索引)。
复合索引的创建方法与创建单一索引的方法完全一样。
但复合索引在数据库操作期间所需的开销更小,可以代替多个单一索引。
当表的行数远远大于索引键的数目时,使用这种方式可以明显加快表的查询速度。
同时有两个概念叫做窄索引和宽索引,窄索引是指索引列为1-2列的索引,如果不特殊说明的话一般是指单一索引。
宽索引也就是索引列超过2列的索引。
设计索引的一个重要原则就是能用窄索引不用宽索引,因为窄索引往往比组合索引更有效。
拥有更多的窄索引,将给优化程序提供更多的选择余地,这通常有助于提高性能。
二.使用
创建索引
create index idx1 on table1(col1,col2,col3)
查询
select * from table1 where col1= A and col2= B and col3 = C
这时候查询优化器,不在扫描表了,而是直接的从索引中拿数据,因为索引中有这些数据,这叫覆盖式查询,这样的查询速度非常快。
三.注意事项
1.何时是用复合索引
在where条件中字段用索引,如果用多字段就用复合索引。
一般在select的字段不要建什么索引(如果是要查询select col1 ,col2, col3 from mytable,就不需要上面的索引了)。
根据where条件建索引是极其重要的一个原则。
注意不要过多用索引,否则对表更新的效率有很大的影响,因为在操作表的时候要化大量时间花在创建索引中.
2.对于复合索引,在查询使用时,最好将条件顺序按找索引的顺序,这样效率最高。
如:IDX1:create index idx1 on table1(col2,col3,col5)
select * from table1 where col2=A and col3=B and col5=D
如果是"select * from table1 where col3=B and col2=A and col5=D"
或者是"select * from table1 where col3=B"将不会使用索引,或者效果不明显
3.复合索引会替代单一索引么?
很多人认为只要把任何字段加进聚集索引,就能提高查询速度,也有人感到迷惑:如果把复合的聚集索引字段分开查询,那么查询速度会减慢吗?带着这个问题,我们来看一下以下的查询速度(结果集都是25万条数据):(日期列fariqi首先排在复合聚集索引的起始列,用户名neibuyonghu排在后列)
IDX1:create index idx1 on Tgongwen(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的查询速度一样是因为查询的条目数一样,如果复合索引的所有列都用上,而且查询结果少的话,这样就会形成“索引覆盖”,因而性能可以达到最优。
同时,请记住:无论您是否经常使用聚合索引的其他列,但其前导列一定要是使用最频繁的列。
[参考: 查询优化及分页算法方案
4.需要在同一列上同时建单一索引和复合索引么?
试验: sysbase 表table1 字段:col1,col2,col3
试验步骤:
(1)建立索引idx1 on col1
执行select * from table1 where col1=A 使用idx1
执行select * from table1 where col1=A and col2=B 也使用idx1
(2)删除索引idx1,然后建立idx2 on (col1,col2)复合索引
执行以上两个查询,也都使用idx2
(3)如果两个索引idx1,idx2都存在
并不是where col1='A'用idx1;where col1=A and col2=B 用idx2。
其查询优化器使用其中一个以前常用索引。
要么都用idx1,要么都用idx2.
由此可见,
(1)对一张表来说,如果有一个复合索引on (col1,col2),就没有必要同时建立一个单索引on col1。
(2)如果查询条件需要,可以在已有单索引on col1的情况下,添加复合索引on (col1,col2),对于效率有一定的提高。
(3)同时建立多字段(包含5、6个字段)的复合索引没有特别多的好处,相对而言,建立多个窄字段(仅包含一个,或顶多2个字段)的索引可以达到更好的效率和灵活性。
5. 一定需要覆盖性查询么?
通常最好不要采用一个强调完全覆盖查询的策略。
如果Select子句中的所有列都被一个非群集索引覆盖,优化程序会识别出这一点,并提供很好的性能。
不过,这通常会导致索引过宽,并会过度依赖于优化程序使用该策略的可能性。
通常,是用数量更多的窄索引,这对于大量查询来说可以提供更好的性能。