From 48f293b9da9e35af179a360bffef77b8a57059f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=8E=E5=81=A5?= <2161737470@qq.com> Date: Thu, 19 Oct 2023 09:58:55 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=BA=8C=E5=8D=81=E4=B8=89=E6=AC=A1?= =?UTF-8?q?=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20231018 \347\264\242\345\274\225.md" | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 "04 \346\235\216\346\230\216\345\201\245/20231018 \347\264\242\345\274\225.md" diff --git "a/04 \346\235\216\346\230\216\345\201\245/20231018 \347\264\242\345\274\225.md" "b/04 \346\235\216\346\230\216\345\201\245/20231018 \347\264\242\345\274\225.md" new file mode 100644 index 0000000..930952b --- /dev/null +++ "b/04 \346\235\216\346\230\216\345\201\245/20231018 \347\264\242\345\274\225.md" @@ -0,0 +1,130 @@ +## 索引 + +### 介绍 + +​ 索引是通过某种算法,构建出一个数据模型,用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到查出相关行(效率慢),如果表中查询的列有一个索引,MySQL能够根据索引快速的找到相关行(效率高),而不必查看所有数据,==节省大量时间==。但是==降低了增、删、改的速度==。 + +### 索引结构 + +#### Hash索引 + +​ 哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。 + +#### B+Tree索引 + +​ B+Tree 索引,是B-Tree的改进版本,同时也是数据库索引索引所采用的存储结构。 数据都在叶子节点上,并且增加了顺序访问指针,每个叶子节点都指向相邻的叶子节点的地址。 + +![](https://s2.loli.net/2023/10/18/4cyXMgPIdaoJvFQ.png) + +### 索引分类 + +| 分类 | 含义 | 特点 | 关键字 | +| ------------ | ------------------------------------ | ------------------------ | -------- | +| **主键索引** | 针对于表中主键创建的索引 | 默认自动创建,只能有一个 | PRIMARY | +| **唯一索引** | 避免同一个表中某数据列中的值重复 | 可以有多个 | UNIQUE | +| **常规索引** | 快速定位特定数据 | 可以有多个 | | +| **全文索引** | 查找文本中的关键词,不比较索引中的值 | 可以有多个 | FULLTEXT | + +### 索引语法 + +**创建索引: 建立索引时一定要指定索引名称** + +1. 在已存在表的中创建索引 + +~~~ mysql +create index 索引名 on 表名(字段名) +~~~ + +2. 通过修改表方式赖添加索引 + +~~~ mysql +alter table 表名 add index 索引名(字段名) +~~~ + +3. 创建表时直接指定索引 + +~~~ mysql +create table emp( + id int primary key, # 创建主键会自动创建一个主键索引 + ename varchar(10), + index 索引名(字段) +); +~~~ + +**查看一张表有哪些索引** + +~~~ mysql +show index from 表名; +~~~ + +**删除索引** + +~~~ mysql +drop index 索引名 on 表名; +~~~ + +**删除主键索引** + +~~~ mysql +alter table 表名 drop primary key; +~~~ + +**最左前缀法则** + +从左开始,左边的索引必须要存在,从左往右查 + +**explain 执行计划** + +~~~ mysql +explain select * from emp; +~~~ + +**运行时间** + +![](https://s2.loli.net/2023/10/19/oLybw8cYTBUMEns.png) + +### 作业 + +~~~ mysql +create table emp( + id int primary key auto_increment, + ename varchar(10), + phone varchar(11), + sex char(1), + hobby varchar(20) +); + +delimiter $$ +create procedure insert_data() +begin + declare i int default 1; + declare ran int; + declare pho double default 18856213040; + a:while true do + set ran = round(rand()+1); + insert into emp values(i,concat('员工',i),pho,case ran when '1' then '女' else '男' end,'打篮球'); + set i = i + 1; + set pho = pho + 1; + if i > 10000000 then leave a; end if; + end while a; +end $$ +delimiter ; +call insert_data(); + + +-- 执行查询文件tb_user.sql,数据准备好了之后,完成如下需求: +-- 1. name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。 +create index idx_name on tb_user(name); +-- 2. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。 +create unique index idx_phone on tb_user(phone); +-- 3. 为profession、age、status创建联合索引。 +create index idx_pas on tb_user(profession,age,`status`); +drop index idx_pas on tb_user; +-- 4. 为email建立合适的索引来提升查询效率。 +create unique index idx_email on tb_user(email); +-- 5. 查看tb_user表的所有的索引数据。 +show index from tb_user; + + +~~~ + -- Gitee