索引是数据库中非常重要的一部分。在查询中增加所以很多时候会比不加索引效率高很多。
在我学习了索引如何使用后,我开始有一些问题,而最根本的原因就是我不知道本质上索引是什么,所以本文就是针对索引的本质来讲下他的原理的。但是只以BTREE为例,其他数据结构或则算法的索引原理会在其他文章讲解。
1.什么是索引?
首先,当我看见有一种索引的创建语句是如下的时候,create index index_name on table_name( column)。我是这样猜测的:我觉得索引首先是取出了一列或者几个特殊的列,然后把他们重命名为index_name,然后存起来了。存的方式就是用特殊的数据结构,比如二叉树。(因为我之前在学习数据结构的时候知道二叉树可以增加查询速度)。但是我不知道他是存在缓存还是哪里?
(我个人习惯在学习一个东西的应用后思考它的本质是怎么回事,然后开始猜测,然后再找资料验证。这是我个人的学习习惯。)
经过我查阅资料,我发现索引是一种数据结构。索引中是包含一个表中列的值和它的物理地址的值,并且这些值存储在一个数据结构中。
注意:
-------索引可以存储的数据结构有多种,常用的有二叉树,还是有哈希表。这个有很多。
-------索引中存的数据:其中只存一个表中的一列或者多列。如果是单索引就是存一列,如果使用的是复合索引就是多列。但是注意不要多列的概念,如果我在一个employee表中有(employee_id,employee_name,employee_age)3个属性。
eg: create index employee_name on employee(employee_name); 那么数据结构中只存employee_name的所有值和employee_name值相应的磁盘物理地址。至于employee_id和employee_age都不会在索引中存在。
eg: create index employee_name on employee(employee_id employee_name)那么存的是employee_id 的值和employee_name的值。但是employee_age不会有。
-------索引被创建后的位置。当我们只建立一个表的时候,我们只有.frm文件。当我们创建索引后,会出现.myi的索引文件。这个文件就是在my.ini中的path路径下(当然很多人找不到这个位置,方法我在这个文章中有写了,有需要的朋友可以链接:https://blog.csdn.net/qq_36098284/article/details/)
2.索引能用来干什么?
当我们创建索引后,会增加查询的效率,多数情况下会比全表扫描要快。
现在我们来解释一下,如果没有索引是怎么进行查询操作的?
看下面的图片:当我们的select是查询empno=4的时候,dbms会生成一个类似指针的东西,从empno=1的地方开始搜索,一直搜索到表的结束,这里是empno=11.
那么有人会问,为什么他搜索到empno=4为什么不停止呢?我们没有索引的select是全表扫描,就是必须把整个表都扫描一次后才告诉dbms,查询结果是什么?
开始的时候我有一个问题,就是如果我们扫描的是主键,当他找到一个结果的时候,因为我用的是where语句,是不是就会停止,答案是,和扫描的是不是主键并没有关系。不添加index就是全表扫描。
所以扫描结果会慢。
现在我们再来看下,如果创建了索引会出现什么情况?为什么就会变快了?
我们还是拿刚刚的举例子,当我们使用二叉树创建的索引,还要扫描empno这属性列的时候,4只需要和6.3.5.4比较4回就会找到结果,和刚刚的11次,相比快了很多。当数据越大的时候,速度就会快的更明显。因为每次都是减掉一半的数据。
(具体的二叉树算法,或者二叉树的数据结构,请看该文,链接:)
3.索引的分类
---------索引类型:主键索引,普通索引,全文索引,唯一索引
3.1主键索引
主键索引的添加:
方法一: 在创建表的时候直接创建
create table table_name(id int unsiged primary key auto_increment,
name varchar(20) not null default ' ' );
方法二:先创建表,后创建index
alter table table_name add primary key ( column_name );
提问:在看完主键索引的创建方式后,你会不会和我一样,觉得这和主键的创建没有区别?
答:主键是字段中唯一不为空值的列,主键是一种约束。同时主键索引是一种特殊的唯一索引。
那么创建主键的时候,数据库会默认为主键创建一个唯一索引,那会为主键创建一个主键索引吗?
他俩是一回事吗?(我在找下资料哈)
3.2全文索引
3.3普通索引
普通索引就是针对普通的列,根据第4点(什么样的列适合做索引)而创建的索引。
创建方式就是先创建表,根据需要选择要创建的索引列。
create index index_name on table_name( column_name );
3.4 唯一性索引
更新中,一个小时候更新。
3.5 索引的查询:
方法一:
desc table_name【缺点:不能查到index的名字】
方法二:
show index(es) from table_name G
3.6 索引的删除:
alter table table_name drop index index_name;
4.哪些时候需要用到索引?
------当这个语句被频繁用作where条件的查询时,最好创建索引
------该字段的列的值很丰富的时候,不是唯一几个值时可以创建索引(比如唯一性太差不适合,例如sex)
-------更新频率不是十分频繁的时候(如果这个列的数据的变化十分的频繁,那么频繁的更改索引文件,会有更多的消耗)
5.使用索引的时候需要注意什么?
------ 使用索引的时候是有代价的:比如占用磁盘的代价;或者对dml(update,insert,destroy)操作的影响。
所以说创建索引增加的效率多数就是对select的,对dml其实是副作用。
------- 对于复合索引来说,只是查询条件使用了最左面的列,索引才会有作用。(复合索引就是多列了)
eg: create index dept add index my_ind(dname,loc);
//dname为最左面的列,loc为右面的列。
失效:select * from dept where loc ='aaa'; 就是这个语句其实在查询的时候没有用到索引。
-------- 对于用模糊查询,查询结果如果是“%aaa”不会使用索引,“aaa%”会使用索引。
关于模糊查询请链接:
原文:https://blog.csdn.net/qq_36098284/article/details/79841094