日期:2014-05-18  浏览次数:20579 次

数据库索引设计原则,请大家积极讨论
在数据库设计中,索引设计是提高查询效率的关键,那么如何设计出合理的索引,设计出高效的索引需要哪些原则,请大家根据实际的应用情况,说说自己的观点。

在表TablePoint数据结构如下
ID schoolId testId subjectId studentId point statisticsTime

select point
from TablePoint
where schoolId = @schoolId And testId = @testId AND subjectId = @subjectId
现有一个疑问,在为了使索引更加有效,因此where子句中的条件的位置的顺序很重要,那么就上面的sql查询语句,如何写才能使索引更加有效(索引大家可以自己定义)

------解决方案--------------------
SQL code


create table TablePoint(
ID                int     identity(1,1)    not null,                
schoolId        int                    not null,                
testId            int                    not null,                
subjectId        int                    not null,                
studentId        int                    not null,                
point            int                    not null,                
statisticsTime    datetime            not null,                
constraint PK_TablePoint PRIMARY KEY NONCLUSTERED (ID)) --ID 不要建聚集索引,主键即可

--将要常用的查询字段做成聚集索引,聚集索引查询效率较高
create CLUSTERED INDEX IX_TablePoint ON TablePoint(schoolId ,testId,subjectId)

------解决方案--------------------
SQL code

--创建索引时的注意事项
/********************************************************************************
 *主题:创建索引时的注意事项
 *说明:本文起点可能会相对高点,首先你的很熟悉索引以及他们的存储结构
 *      有很多地方你可能觉得有异议,欢迎一起讨论

 *作者:筱筱澄(姐只想当个嫂子)
 *日期:2012.06.15
 *另外:转载请著名出处。
**********************************************************************************/

------解决方案--------------------
建索引
1.一般你查询语句where条件中的内容大都是需建索引的,复合索引一般经常会用到的
2.经常用于排序的字段,一般也需要的
3.查询外表关联的字段
。。。
少建索引
1.update时比较多的表,应少建索引
2.字段值比较少的,如1亿条数据,一个类别就那几种就算了
。。。

索引一般需定期重建的
------解决方案--------------------
SQL code

使用聚集索引和非聚集索引的区别
使用聚集索引 

    聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。避免每次查询该列时都进行排序,从而节省成本。 

注意事项 
定义聚集索引键时使用的列越少越好。 
1、包含大量非重复值的列。 
2、使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。 
3、被连续访问的列。 
4、返回大型结果集的查询。 
5、经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。 
6、OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。 


聚集索引不适用于: 

1、频繁更改的列 。这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

2、宽键 。来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。

使用非聚集索引 

非聚集索引与课本中的目录类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。 

多个非聚集索引 
有些书籍包含多个索引。例如,一本介绍园艺的书可能会包含一个植物通俗名称索引,和一个植物学名索引,因为这是读者查找信息的两种最常用的方法。对于非聚集索引也是如此。可以为在表中查找数据时常用的每个列创建一个非聚集索引。 


注意事项

在创建非聚集索引之前,应先了解您的数据是如何被访问的。可考虑将非聚集索引用于: 
? 包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其它列)。如果只有很少的非重复值,如只有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效。 
? 不返回大型结果集的查询。 
? 返回精确匹配的查询的搜索条件(WHERE 子句)中经常使用的列。 
? 经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列上创建多个非聚集索引,在任何外键列上创建一个聚集索引。 
? 在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。

索引都是一种排序,只是聚集索引的排序和物理表中的数据排序相同,一致的;而非聚集索引的排序和物理表数据的排序不同。

当我们在更新统计信息的时候,对于那些聚集索引列不但要更新索引页还要同时对数据物理表数据重新排序;而对非聚集索引列则只需要更新索引页

------解决方案--------------------
SQL code
---使用索引优化数据库查询效率
1.不宜创建索引的情形
(1)经常插入,修改和删除的表
(2)数据量比较小的表,因为查询优化器在搜索索引时所花费的时间可能会大于遍历全表的数据所需要的时间

2.适合创建索引的情形
(1)为where子句中出现的列创建索引
(2)创建组合索引
(3)为group by 子句中出现的列创建索引

3.聚集索引的设计原则
(1)该列的数值是唯一的或者很少有重复的记录
(2)经常使用between ...and..按顺序查询的列
(3)定义identity的唯一列.
(4)经常用于对数据进行排序的列.

------解决方案--------------------
INCLUDE索引中附加数据,但是索引排序不计算include子句里的列,就是说没有include子句的索引通过索引查询后取point的值需要再走一次指针才能取到,INCLUDE的话point的值在索引的叶子节点中可以直接取到值,少了一个步骤。和覆盖索引不同的是,如果把point放到索引中区索引排序是要计算point的,但是include是不用的。