如果我们新建一个没加主键的表,那么当我们向表中插入数据时,这些数据会无序的存放在磁盘存储器上,一行一行的排列的很整齐, 这样的数据在表中是无序的,只与插入顺序有关。当我们想要查询表中数据时,这时只能拿着查询条件一条一条逐一的与数据库中的数据进行比较,如果匹配到的数据正好是最后一条,这样一次查询就把表中的所有数据都匹配了一遍。如果数据库中只有几百条数据,这样的查询或许不会让你抓狂,但如果数据库中有几百万甚至几千万条的数据时,这样的查询效率就让你不止抓狂了。这时候或许你就要给表中的某个字段建立索引,来提高查询的效率。那么何为索引呢?建立索引为什么就能提高查询效率呢?下面就来详细学习一下。
二、索引 1、何为索引?在关系型数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。(说白了,就是索引列的值和指向具体某一条记录的指针)
索引提供指向存储在表的指定列中的数据值的指针,然后根据你指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。
当表中有大量记录时,若要对表进行查询,第一种搜索信息方式是全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录,这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作;第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的 ROWID(相当于页码)快速找到表中对应的记录。
索引是为了加速对表中数据行的检索而创建的一种分散的存储结构。索引是针对表而建立的,它是由数据页面以外的索引页面组成的,每个索引页面中的行都会含有逻辑指针,以便加速检索物理数据。(☆☆☆☆☆)
2、索引类型根据数据库的功能,可以在数据库设计器中创建四种索引:普通索引、唯一索引、主键索引、聚集索引。
(1)、普通索引最基本的索引类型,没有唯一性之类的限制。普通索引可以通过以下几种方式创建:
创建索引,例如:create index on tablename (列的列表);
修改表方式创建索引,例如:alter table tablename add index [索引的名字] (列的列表);
创建表的时候指定索引,例如:create table tablename ( [...], index [索引的名字] (列的列表) );
(2)、唯一索引(UNIQUE:建立唯一索引)
唯一索引是不允许其中任何两行具有相同索引值的索引。当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。例如,如果在 employee 表中员工的姓名 (name) 上创建了唯一索引,则任何两个员工都不能同姓。
对某个列建立UNIQUE索引后,插入新纪录时,数据库管理系统会自动检查新纪录在该列上是否取了重复值,在CREATE TABLE 命令中的UNIQE约束将隐式创建UNIQUE索引。
创建唯一索引的几种方式:
创建索引,例如:create unique index on tablename (列的列表);
修改表方式创建索引,例如:alter table tablename add unique [索引的名字] (列的列表);
创建表的时候指定索引,例如:create table tablename ( [...], unique [索引的名字] (列的列表) );
(3)、主键索引
简称主索引,数据库表中一列或列组合(字段)的值唯一标识表中的每一行。该列称为表的主键。在数据库中,为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。
尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议使用主键索引。
(4)、聚集索引(CLUSTERED:建立聚集索引。)在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引, 即如果存在聚集索引,就不能再指定CLUSTERED 关键字。一个表中只能有一个聚集索引,但表中的每一列都可以有自己的非聚集索引。
索引不是聚集索引(非聚集索引),则表中行的物理顺序与键值的逻辑(索引)顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。聚集索引更适用于对很少对基表进行增删改操作的情况。
如果在表中创建了主键约束,SQL Server将自动为其产生唯一性约束。在创建主键约束时,指定了CLUSTERED关键字或干脆没有制定该关键字,SQL Sever将会自动为表生成唯一聚集索引。
3、索引的优缺点 (1)、优点1)、大大加快数据的检索速度;
2)、创建唯一性索引,保证数据库表中每一行数据的唯一性;
3)、加速表和表之间的连接;
4)、在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
(2)、缺点
1)、索引需要占物理空间。
2)、当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。
三、索引的存储结构
在MySQL引擎与锁机制一文中说过,InnoDB和MyISAM两种引擎所使用的索引的数据结构都是B+树。
1、索引原理在数据库中查找数据面临着等值查询,还有范围查询(>、、 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
(2)、= 和 in 可以乱序。比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,MySQL的查询优化器会帮你优化成索引可以识别的形式。
(3)、尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例。比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录。
(4)、索引列不能参与计算,保持列“干净”。比如from_unixtime(create_time) = ’2019-01-13’就不能使用到索引,原因很简单,B+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2019-01-13’)。
(5)、尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
四、小结1、索引树结构中各节点的值来自于表中的索引字段, 假如给user表的name字段加上索引 , 那么索引就是由name字段中的值构成。
2、聚集索引决定了表中数据的物理存储顺序,那么一个表则有且只有一个聚集索引。聚集索引的优势是很明显的,而每个表中只能有一个聚集索引的规则,这使得聚集索引变得更加珍贵。
3、如果给表加上了主键,那么表在磁盘上的存储结构就由整齐排列的结构转变成了树状结构,也就是平衡树结构,换句话说,就是整个表就变成了一个索引。
4、主键的作用就是把表的数据格式转换成索引(平衡树)的格式放置。