首页 > 数据库技术 > 详细

MySQL索引实践

时间:2019-10-13 19:30:37      阅读:81      评论:0      收藏:0      [点我收藏+]

数据库索引本质上是一种数据结构(存储结构+算法),目的是为了加快数据检索速度。

1、索引的类型(待完善)

主键索引:给表设置主键,这个表就拥有主键索引。

唯一索引:unique

普通索引:增加某个字段的索引,比如用户表根据用户名查询。

组合索引:使用多个字段创建索引,遵循最左原则,比如创建索引(col1 + col2 + col3),相当于创建了(col1)、(col1,col2)、(col,col2,col3)三个索引。

全文索引:

2、聚簇索引与非聚簇索引(待完善)

MySQL的InnoDB主键使用的是聚簇索引,MyISAM 不管是主键索引,还是二级索引使用的都是非聚簇索引。

技术分享图片

非聚簇索引(右图),表数据和索引是分成两部分存储的,主键索引和二级索引存储上没有任何区别。使用的是B+树作为索引的存储结构,所有的节点都是索引,叶子节点存储的是索引+索引对应的记录的地址。

聚簇索引(左图),表数据是和主键一起存储的,主键索引的叶结点存储行数据(包含了主键值),二级索引的叶结点存储行的主键值。使用的是B+树作为索引的存储结构,非叶子节点都是索引关键字,但非叶子节点中的关键字中不存储对应记录的具体内容或内容地址。叶子节点上的数据是主键与具体记录(数据内容)。

聚簇索引优点:

①当你需要取出一定范围内的数据时,用聚簇索引也比用非聚簇索引好。
②当通过聚簇索引查找目标数据时理论上比非聚簇索引要快,因为非聚簇索引定位到对应主键时还要多一次目标记录寻址,即多一次I/O

聚簇索引缺点:

①插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键。
②更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。
③二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。
二级索引的叶节点存储的是主键值,而不是行指针(非聚簇索引存储的是指针或者说是地址),这是为了减少当出现行移动或数据页分裂时二级索引的维护工作,但会让二级索引占用更多的空间。
④采用聚簇索引插入新值比采用非聚簇索引插入新值的速度要慢很多,因为插入要保证主键不能重复,判断主键不能重复,采用的方式在不同的索引下面会有很大的性能差距,聚簇索引遍历所有的叶子节点,非聚簇索引也判断所有的叶子节点,但是聚簇索引的叶子节点除了带有主键还有记录值,记录的大小往往比主键要大的多。这样就会导致聚簇索引在判定新记录携带的主键是否重复时进行昂贵的I/O代价。

 3、索引实践(待完善)

#创建班级表
CREATE TABLE class
(
pid INTEGER not null AUTO_INCREMENT,
class_code VARCHAR(200) not null,
class_name VARCHAR(200) not null,
created_by VARCHAR(200),
created_date DATE,
updated_by VARCHAR(200),
updated_date DATE,
CONSTRAINT pk_class_pid PRIMARY KEY(pid)
);

#插入数据
insert into stu.class (class_code,class_name,created_by,created_date,updated_by,updated_date)
values
( ‘1-001‘, ‘一年级1班‘,‘system‘, NOW(),‘system‘,NOW()),
( ‘1-002‘, ‘一年级2班‘,‘system‘, NOW(),‘system‘,NOW()),
( ‘2-001‘, ‘二年级1班‘,‘system‘, NOW(),‘system‘,NOW()),
( ‘2-002‘, ‘二年级2班‘,‘system‘, NOW(),‘system‘,NOW());

 #使用主键索引

EXPLAIN
select * from class where pid = 2;

技术分享图片

  #创建普通索引

CREATE INDEX idx_class_class_code ON class(class_code);
#使用索引
EXPLAIN
select * from class where class_code = ‘2-001‘;

技术分享图片

  #创建组合索引

CREATE INDEX idx_class_class_code_name ON class(class_code,class_name);
#使用索引
EXPLAIN
select * from class where class_code = ‘2-001‘ and class_name = ‘一年级2班‘;
#使用索引,组合索引所有字段与顺序无关
EXPLAIN
select * from class where class_name = ‘一年级2班‘ and class_code = ‘2-001‘;

技术分享图片

  #组合索引只使用第一个字段时,索引可生效

#删除索引
DROP INDEX idx_class_class_code ON class;

EXPLAIN
select * from class where class_code = ‘2-001‘;

技术分享图片

  #未使用索引,遵循最左原则

EXPLAIN
select * from class where class_name = ‘一年级2班‘;

技术分享图片

 #创建唯一索引

CREATE UNIQUE INDEX idx_uq_class_class_code ON class(class_code);
#删除已有的组合索引
DROP INDEX idx_class_class_code_name ON class;
#使用唯一索引
EXPLAIN
select * from class where class_code = ‘2-001‘;

技术分享图片 

MySQL索引实践

原文:https://www.cnblogs.com/wangymd/p/11667412.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!