目录

数据库造神计划第十七天-索引2

数据库造神计划第十七天—索引(2)

https://i-blog.csdnimg.cn/direct/7d591b544f874d8a8495f2f641c7d7a5.jpeg

🔥个人主页:

🎬作者简介:Java研发方向学习者

📖个人专栏:、《

⭐️人生格言:没有人生来就会编程,但我生来倔强!!!


https://i-blog.csdnimg.cn/direct/7bc50643513c4841ab37a6a5e97eb4b5.gif



续接上一话:

一、B+在MySQL索引中的应用

        非叶子节点保存索引数据,叶子节点保存真实数据,如下图所示

https://i-blog.csdnimg.cn/direct/1a2ea12786a94f049e741b864aeec452.png

以查找id为5的记录,完整的检索过程如下:

        首先判断B+树的根节点中的索引记录,此时 5 < 7 ,应访问左孩子节点,找到索引页2

        在索引页2中判断id的大小,找到与5相等的记录,命中,加载对应的数据页

以上的IO过程,加载索引页1–>加载索引页2–>加载数据页3

1、计算三层树高的B+树可以存放多少条记录

(了解一些计算,要有一点基本的估算能力)

        假设⼀条用户数据大小为1KB,在忽略数据页中数据页自⾝属性空间占用的情况下,一页可以存16 条数据

        索引页一条数据的大小为,主键用BIGINT类型占8Byte,下一页地址6Byte,⼀共是14Byte,⼀个索引页可以保存 16*1024/14 = 1170 条索引记录

        如果只有三层树高的情况,综合只保存索引的根节点和⼆级节点的索引页以及保存真实数据的数据页,那么⼀共可以保存 1170117016 = 21,902,400 条记录,也就是说在两千多万条数据的 表中,可以通过三次IO就完成数据的检索

二、索引分类

1、主键索引

        当在⼀个表上定义⼀个主键 PRIMARY KEY 时,InnoDB使用它作为聚集索引。

        推荐为每个表定义⼀个主键。如果没有逻辑上唯一且非空的列或列集可以使用主键,则添加⼀个自增列。

2、普通索引

        最基本的索引类型,没有唯⼀性的限制。

        可能为多列创建组合索引,称为复合索引或组全索引

3、唯⼀索引

        当在⼀个表上定义⼀个唯⼀键 UNQUE 时,自动创建唯⼀索引。

        与普通索引类似,但区别在于唯⼀索引的列不允许有重复值。

4、全文索引

        基于文本列(CHAR、VARCHAR或TEXT列)上创建,以加快对这些列中包含的数据查询和DML操作

        用于全文搜索,仅MyISAM和InnoDB引擎支持。

5、聚集索引

        与主键索引是同义词

        如果没有为表定义 PRIMARY KEY, InnoDB使用第⼀个 UNIQUE 和 NOT NULL 的列作为聚集索引。

        如果表中没有PRIMARY KEY 或合适的 UNIQUE 索引,InnoDB会为新插入的行生成⼀个行号并用6字节的ROW_ID 字段记录, ROW_ID 单调递增,并使用ROW_ID 做为索引。

6、非聚集索引

        聚集索引以外的索引称为非聚集索引或⼆级索引

        ⼆级索引中的每条记录都包含该行的主键列,以及⼆级索引指定的列。

        InnoDB使用这个主键值来搜索聚集索引中的行,这个过程称为回表查询

7、索引覆盖

        当⼀个select语句使用了普通索引且查询列表中的列刚好是创建普通索引时的所有或部分列,这时就可以直接返回数据,而不用回表查询,这样的现象称为索引覆盖

三、使用索引

1、自动创建

        当我们为⼀张表加主键约束(Primarykey),外键约束(ForeignKey),唯⼀约束(Unique)时, MySQL会为对应的的列自动创建⼀个索引

        如果表不指定任何约束时,MySQL会自动为每⼀列生成⼀个索引并用ROW_ID 进行标识

2、手动创建

2.1主键索引

# ⽅式⼀,创建表时创建主键
create table t_test_pk (
    id bigint primary key auto_increment,
    name varchar(20)
);

# ⽅式⼆,创建表时单独指定主键列
create table t_test_pk1 (
    id bigint auto_increment,
    name varchar(20),
    primary key (id)
);

# ⽅式三,修改表中的列为主键索引
create table t_test_pk2 (
    id bigint,
    name varchar(20)
);

alter table t_test_pk2 add primary key (id) ;
alter table t_test_pk2 modify id bigint auto_increment;

2.2唯⼀索引

# ⽅式⼀,创建表时创建唯⼀键
create table t_test_uk (
    id bigint primary key auto_increment,
    name varchar(20) unique
);
 
# ⽅式⼆,创建表时单独指定唯⼀列
create table t_test_uk1 (
    id bigint primary key auto_increment,
    name varchar(20),
    unique (name)
);
 
# ⽅式三,修改表中的列为唯⼀索引
create table t_test_uk2 (
    id bigint primary key auto_increment,
    name varchar(20)
);
 
alter table t_test_uk2 add unique (name) ;

2.3普通索引

# ⽅式⼀,创建表时指定索引列
create table t_test_index (
    id bigint primary key auto_increment,
    name varchar(20) unique
    sno varchar(10),
    index(sno)
);
 
# ⽅式⼆,修改表中的列为普通索引
create table t_test_index1 (
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10)
);

alter table t_test_index1 add index (sno) ;
 
# ⽅式三,单独创建索引并指定索引名
create table t_test_index2 (
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10)
);

create index index_name on t_test_index2(sno);

3、创建复合索引

        创建语法与创建普通索引相同,只不过指定多个列,列与列之间用逗号隔开

# ⽅式⼀,创建表时指定索引列
create table t_test_index4 (
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10),
    class_id bigint,
    index (sno, class_id)
);

# ⽅式⼆,修改表中的列为复合索引
create table t_test_index5 (
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10),
    class_id bigint
);
 
alter table t_test_index5 add index (sno, class_id);
 
# ⽅式三,单独创建索引并指定索引名
create table t_test_index6 (
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10),
    class_id bigint
);

create index index_name on t_test_index6 (sno, class_id);

4、查看索引

# ⽅式⼀:show keys from 表名
show keys from t_test_index6;

https://i-blog.csdnimg.cn/direct/cec9a4dd0beb41008ac8616e566cf831.png

# ⽅式⼆
show index from t_test_index6;

# ⽅式三,简要信息:desc 表名;
desc t_test_index6;

5、删除索引

5.1主键索引

# 语法
alter table 表名 drop primary key;
 
# 示例,删除t_test_index6表中的主键
alter table t_test_index6 drop primary key;

https://i-blog.csdnimg.cn/direct/4abab742ada04209bd5df7caa8c1957f.png

# 如查提⽰由于⾃增列的错误,先删除⾃增属性
alter table t_test_index6 modify id bigint;

https://i-blog.csdnimg.cn/direct/51d8611f895e4ac19f45d2d43f22ad60.png

# 重新删除主键
alter table t_test_index6 drop primary key;

https://i-blog.csdnimg.cn/direct/d7f95382c9d440a48e53ed9ad518c1e4.png

# 查看结果
show keys from t_test_index6;

https://i-blog.csdnimg.cn/direct/14c066a9081d4555bb3df515ccf63ea4.png

5.2其他索引

# 语法alter table 表名 drop index 索引名;

# ⽰例,删除t_test_index6表中名为index_name的索引
alter table t_test_index6 drop index index_name;

# 查看结果
show keys from t_test_index6;

https://i-blog.csdnimg.cn/direct/3cfb7a703a174c09af19697968ebab83.png

6、创建索引的注意事项

        索引应该创建在高频查询的列上

        索引需要占用额外的存储空间

        对表进行插入、更新和删除操作时,同时也会修索引,可能会影响性能

        创建过多或不合理的索引会导致性能下降,需要谨慎选择和规划索引