一、索引的介绍
介绍
索引类似于书本字典的目录;帮助mysql高效获取数据的数据结构。
为什么要引入索引:
① 提高查询效率,尽量避免全表扫描;
② 索引本身也很大,要根据情况添加索引(数据量较少时,添加索引可能比不添加索引更占空间);
③ 索引往往以索引文件的形式存储在磁盘上。
索引的使用场景:
- 一、应创建索引的场景:
1、经常使用在where子句上的列;
2、经常需要排序的列;
3、经常需要根据范围搜索;
4、经常用在连接的列:外键
5、作为主键的列;
6、经常需要搜索的列;
二、不应该创建索引的场景:
1、很少搜索的列;
2、具有很少数据值的列;
3、定义为text、image的列,因为这些列数据量相当大;
4、对修改性能远大于搜索性能时,因为当增加索引时,会提高搜索性能,但是会降低修改性能;
二、索引的优缺点
优点:
1、提高数据的检索效率,降低数据库的io成本;
2、通过索引列对数据进行排序,降低数据排序的成本,降低了cpu的消耗。
缺点:
1、索引也是一张表,保存了主键和索引字段,指向实体表的记录,所以索引列也要占空间;
2、索引提高查询速度,但会降低更新速度,原因是更新索引列时,会动态更新索引;
3、索引只是提高效率的一个因素,大数据量时,需要建立最优秀的索引或者优化查询语句,索引是根据不同业务场景进行调整的。
三、索引的类别
mysql主要的索引类型:普通索引、唯一索引、主键索引、组合索引、全文索引
1、普通索引
是最基本的索引,值可以为空,仅加速查询。
(1)创建索引:create index index_name on table(column(length));
(2) 修改表结构的方式添加索引:alter table table_name add index index_name on (column(length));
(3) 删除索引:drop index index_name on table;
2、唯一索引
唯一索引与普通索引类似,不同的是:索引列的值必须唯一,允许有空值。如果是组合索引
则列值的组合必须唯一。简单来说:唯一索引是加速查询 列值唯一(可以有null)。
(1)创建唯一索引:create unique index indexname on table(column(length));
(2) 修改表结构:alter table table_name add unique indexname on (column(length));
3、主键索引
主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。
简单来说:主键索引是加速查询 列值唯一(不能有null) 表中只有一个。
(1)一般是在建表的时候创建主键索引:
create table mytable(id int not null,username varchar(20) not null,primary key(id));
4、组合索引
组合索引指在多个字段上创建的索引,查询条件中只有使用了创建索引时的第一个字段,索引才会被使用。注意:使用组合索引时遵循最左前缀集合。组合索引时多列值组成的一个索引,专门用于组合搜索,效率大于索引合并。
(1)创建索引:alter table tablename add index name_name_age (name,age,city);
5、全文索引
①全文索引主要用来查找文本中的关键字,而非直接与索引中的值比较;
②目前只有char、vatchar、text列上可以创建全文索引;
③数据量大时,先将数据放入没有全局索引的表,然后再用create index创建全文索引优于先为表创建全文索引,然后再写入数据;
(1)创建表的全文索引:
create table `table`
( `id` int(11) not null auto_increment ,
`title` char(255) character not null ,
`content` text character null ,
`time` int(10) null default null ,
primary key (`id`),
fulltext (content) );
(2)修改表结构添加全文索引: alter table article add fulltext index_content(content);
(3)直接创建索引:create fulltext index_content on article(content);
1.添加primary key(主键索引):alter table `table_name` add primary key ( `column` )
2.添加unique(唯一索引):alter table `table_name` add unique (`column`)
3.添加index(普通索引):alter table `table_name` add index index_name ( `column` )
4.添加fulltext(全文索引):alter table `table_name` add fulltext (`column`)
注意:mysql的索引结构主要包括:btree索引,hash索引,full-text索引,r-tree索引
如果么有特别指明,都是指b 树结构的索引;
innodb存储引擎中的b 树索引是由二叉查找树、平衡二叉树和b树这三种数据结构演化过来的。
四、索引的失效与生效
1、like 模糊查询 前模糊或者 全模糊不走索引;
2、or 条件中只要有一个字段没有索引,该语句就不走索引;
3、使用 union all 代替 or 这样的话有索引例的就会走索引;
4、in 走索引,not in 不走索引;
5、is null 走索引,is not null 不走索引;
6、!=、<> 不走索引;
7、隐式转换-不走索引(name 字段为 string类型,这里123为数值类型,进行了类型转换,所以不走索引,改为 '123' 则走索引);
8、函数运算-不走索引;
9、and 语句,多条件字段,最多只能用到一个索引,如果需要,可以建组合索引;
如果查看执行计划分析是否使用索引?
pl_sql(oracle):
1、使用执行语句:exptain plan eor 执行sql
2、接着执行:select * from table (dbms xplan.display);
或者直接 选中需要查询的sql语句,按快捷键 f5 即可查看执行计划。
五、聚集索引和非聚集索引的区别(mysql)
一、从物理存储的方式来进行区别的
聚集索引也叫聚簇索引
① 聚集索引和聚簇索引不是一种索引类型,而是物理存储的方式而已;
② innodb默认数据结构是聚簇索引,而myisam是非聚簇索引;
如图所示:实际上是从物理存储的方式来进行区别的,分别为innodb和myisam的物理存储
① 聚集索引的物理存储有 表结构 和 表索引 数据 两个文件;由于索引和数据聚集在同一文件中,所以称为聚集索引;
② 非聚集索引的物理存储有 表结构 和 表数据 和 表索引三个文件;由于索引和数据没有被聚集在同一文件中,所以称为非聚集索引;
二、底层数据结构从数据检索来区别:
聚集索引:
① innodb的数据文件.frm和数据文件.ibd,其中.ibd中存放的是数据和索引信息是存放在一起的;
② 表的数据行都存放在索引树的叶子节点中;
③ 索引和数据保存在同一个b-tree中,因此从聚集索引中获取数据通常比在非聚集索引中查找要快。
非聚集索引:
① myisam的索引文件.myi和数据文件.myd是分开存储的;
② 叶子节点中保存的实际上是指向存放数据块的指针;
③ 非聚集索引需要先查询一遍索引文件,得到索引,根据索引获取数据。
三、关于聚集索引和非聚集索引的几个问题
1、在主键上创建聚集索引的表插入数据为什么比主键上创建非聚集索引表要慢?
由于有主键唯一性的约束,所以需要保证插入的数据没有重复;
聚集索引由于索引叶节点就是数据页,所以想检查主键的唯一性,需要遍历所有数据节点才行;但非聚集索引不同,由于非聚集索引上包含了主键值,所以查主键唯一性,只需要遍历所有的索引页就行(索引的存储空间比实际数据更少),这比遍历所有数据行减少了不少io消耗。
2、在数据库中通过什么描述聚集索引与非聚集索引?
索引是通过二叉树的形式进行描述的;
聚集索引和非聚集索引的区别是:
聚集索引的叶节点就是最终的数据节点;
非聚集索引的叶节点仍是索引节点,但它有一个指向最终数据的指针。