索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
1.数据库索引定义
数据库索引好比是一本书前面的目录,能加快数据库的查询速度。数据库的索引一般是B树索引,结构如图3-1所示。
例如这样一个查询:select * from table1 where id=44。如果没有索引,必须遍历整个表,直到找到ID等于44的这一行为止;有了索引之后(必须是在ID这一列上建立的索引),直接在索引(B-树结构或者hash结构)里面找44(也就是在ID这一列找),顺着索引的数据结构可以很快得知这一行的位置,从而快速找到这一行。可见,索引是用来定位的。
索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了。聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。索引又可以分为普通索引和唯一性索引:
普通索引:如CREATE INDEX mycolumn_index ON mytable(myclumn)。
唯一性索引:保证在索引列中的全部数据是唯一的,对聚簇索引和非聚簇索引都可以使用CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)。
虽然建立索引的目的是加快对表中记录的查找或排序。但是为表设置索引也要付出代价的:一是增加了数据库的存储空间;二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。
索引基于数据库表中的某些列而建立。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引:
在经常需要搜索的列上,可以加快搜索的速度。
在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构。
在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度。
在经常需要根据范围进行搜索的列上,因为索引已经排序,其指定的范围是连续的。
在经常需要排序的列上,因为索引已经排序,这样查询可以利用索引的排序缩短排序查询时间。
在经常使用在WHERE子句中的列上,加快条件的判断速度。
同样,对于有些列不应该创建索引。一般来说,不应该创建索引的这些列具有下列特点:
第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
第三,对于那些定义为text、image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少,不利于使用WHERE条件进行检索。
第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改操作远远多于检索操作时,不应该创建索引。
总体来说,索引的特点如下:
索引可以加快数据库的检索速度。
索引降低了数据库插入、修改、删除等维护任务的速度。
使用查询处理器执行SQL语句,在一个表上,一次只能使用一个索引。
2.数据库优化
(1)配置缓存
建立缓存机制。当数据量增加时,一般的处理工具都要考虑到缓存问题。缓存大小设置的好坏也关系到数据处理的成败,例如,在处理2亿条数据聚合操作时,缓存设置为10万条/Buffer,对于这个级别的数据量这是可行的。缓存包括如下几种:
索引缓存(key_buffer)
排序缓存(sort_buffer)
查询缓存(query_buffer)
表描述符缓存(table_cache)
(2)切表
切表也是一种比较流行的数据库优化法。分表包括两种方式:横向分表和纵向分表。其中,横向分表比较有使用意义,顾名思义,横向切表就是指把记录分到不同的表中,而每条记录仍旧是完整的(纵向切表后每条记录是不完整的),例如原始表中有100条记录,要切成2个表,那么最简单也是最常用的方法就是ID取摸切表法,本例中,就把ID为1,3,5,7,…的记录存在一个表中,ID为2,4,6,8,…的记录存在另一个表中。虽然横向切表可以减少查询强度,但是它也破坏了原始表的完整性,如果该表的统计操作比较多,那么不适合横向切表。横向切表有个非常典型的用法,就是用户数据——每个用户的用户数据一般都比较庞大,但是每个用户数据之间的关系不大,因此这里很适合横向切表。最后,要记住一句话就是:分表会造成查询负担,因此在数据库设计之初,要想好是否真的适合切表的优化。
切表分为如下两种形式:
纵向:字段较多时可以考虑,一般用处不大。
横向:
能有效降低表的大小,减少由于枷锁导致的等待。
查询会变得复杂,尤其是需要排序的查询。
3.单个索引和复合索引
单个索引:即非复合索引。
复合索引:又叫组合索引,在索引建立语句中同时包含多个字段名,最多16个字段CREATE INDEX name_index ON username(firstname,lastname)。
在SQL中,我们经常以为建立了索引,SQL查询的时候就会如我们所希望的那样使用索引。事实上,SQL只会在一定条件下使用索引。这里我们总结一条规律:SQL会在条件中包含了前导列时使用索引,即查询条件中必须使用索引中的第一个列,且查询条件中的列最好与索引中的相同。