数据库索引
MySQL索引底层结构是B+树,B+树作为树的一种实现,能够让我们很快地查找出对应的记录
B+树是
如果一棵普通的树在极端的情况下,是能退化成链表的(树的优点就不复存在了)
B+树是平衡树的一种,是不会退化成链表的,树的高度都是相对比较低的(基本符合矮矮胖胖(均衡)的结构)
-
B+树是一颗平衡树,如果我们对这颗树增删改的话,那肯定会破坏它的原有结构。
-
要维持平衡树,就必须做额外的工作。正因为这些额外的工作开销,导致索引会降低增删改的速度
索引的特点
-
(1)索引一旦建立,Oracle管理系统会对其进行自动维护, 而且由Oracle管理系统决定何时使用索引
-
(2)用户不用在查询语句中指定使用哪个索引
-
(3)在定义primary key或unique约束后系统自动在相应的列上创建索引
-
(4)用户也能按自己的需求,对指定单个字段或多个字段,添加索引
需要注意的是:Oracle是自动帮我们管理索引的,并且如果我们指定了primary key或者unique约束,系统会自动在对应的列上创建索引..
什么时候【要】创建索引
-
(1)表经常进行 SELECT 操作
-
(2)表很大(记录超多),记录内容分布范围很广
-
(3)列名经常在 WHERE 子句或连接条件中出现
什么时候【不要】创建索引
-
(1)表经常进行 INSERT/UPDATE/DELETE 操作
-
(2)表很小(记录超少)
-
(3)列名不经常作为连接条件或出现在 WHERE 子句中
索引优缺点:
-
索引加快数据库的检索速度
-
索引降低了插入、删除、修改等维护任务的速度(虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引)
-
唯一索引可以确保每一行数据的唯一性,通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能
-
索引需要占物理和数据空间
索引分类:
-
唯一索引:唯一索引不允许两行具有相同的索引值
-
主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空
-
聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个
-
非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个
-
聚集索引就是以主键创建的索引
-
非聚集索引就是以非主键创建的索引
-
普通索引:即一个索引只包含单个列,一个表可以有多个单列索引
-
复合索引:即一个索引包含多个列
-
索引管理
创建索引
-
创建普通索引
CREATE INDEX index_name ON table_name1(col_name);
-
创建唯一索引
CREATE UNIQUE INDEX index_name ON table_name1(col_name);
-
创建组合索引
CREATE INDEX index_name ON table_name1(col_name1,col_name2,col_name3);
相当于创建了下面三个索引:
-
col_name1,col_name2,col_name3
-
col_name1,col_name2
-
col_name1
修改索引
ALTER table_name1 ADD INDEX index_name ON (col_name);
删除索引
DROP INDEX index_name ON table_name1;
索引使用
-
where
只有where的情况,遵从最左原则,条件必须有左边的字段,才会用到索引,中间如果断开了,则都不会用到后面的索引
-
like
不以通配符 % 和 _ 开头作查询时,会使用索引,如下
# 会使用索引
SELECT * FROM mytable WHERE username like'admin%'
# 不会使用索引
SELECT * FROM mytable WHEREt Name like'%admin'
-
group by 和 order by
没有where语句,group by 、 order by 不会使用索引, 有where,group by 、 order by 会使用索引,使用条件和where一样
索引总结
索引在数据库中是一个非常重要的知识点!上面谈的其实就是索引最基本的东西,要创建出好的索引要顾及到很多的方面:
-
1,最左前缀匹配原则。这是非常重要、非常重要、非常重要(重要的事情说三遍)的原则,MySQL会一直向右匹配直到遇到范围查询
(>,<,BETWEEN,LIKE)
就停止匹配。 -
2,尽量选择区分度高的列作为索引,区分度的公式是
COUNT(DISTINCT col)/COUNT(*)
。表示字段不重复的比率,比率越大我们扫描的记录数就越少。 -
3,索引列不能参与计算,尽量保持列“干净”。比如,
FROM_UNIXTIME(create_time)='2016-06-06'
就不能使用索引,原因很简单,B+树中存储的都是数据表中的字段值,但是进行检索时,需要把所有元素都应用函数才能比较,显然这样的代价太大。所以语句要写成 :create_time=UNIX_TIMESTAMP('2016-06-06')
。 -
4,尽可能的扩展索引,不要新建立索引。比如表中已经有了a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
索引介绍以及索引原理
https://blog.csdn.net/weixin_42181824/article/details/82261988