From 830516906d1dcbcbe2fa3ab7c27b1ffede783a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=91=A8=E7=86=A0?= <2108439463@qq.com> Date: Fri, 18 Oct 2024 11:31:51 +0800 Subject: [PATCH 1/2] 10/18 --- .../24 20241018 \347\264\242\345\274\225.md" | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 "\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" diff --git "a/\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" "b/\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" new file mode 100644 index 0000000..43def55 --- /dev/null +++ "b/\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" @@ -0,0 +1,191 @@ +# 一、笔记 + +[一文搞懂MySQL索引(清晰明了)-CSDN博客](https://blog.csdn.net/wangfeijiu/article/details/113409719) + +# 1. 索引的优缺点 + +``` +优点:面对大量数据,能有效提升查速度。 +缺点:数据越大,创建和维护索引的时间成本就越高。 +``` + +# 2.创建索引准则 + +在经常需要搜索的列上,可以加快搜索的速度 +在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构 +在经常用在连接(JOIN)的列上,这些列主要是一外键,可以加快连接的速度 +在经常需要根据范围(<,<=,=,>,>=,BETWEEN,IN)进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的 +在经常需要排序(order by)的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; +在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 + +# 3.**索引结构** + +## 1.B-TREE + +![image-20241018110109424](https://gitee.com/luo-zhouyi/note-sheet-bed/raw/master/text/img/upgit_20241018_1729220469.png) + +B树的特征: + +- 关键字集合分布在整颗树中; +- 任何一个关键字出现且只出现在一个结点中; +- 搜索有可能在非叶子结点结束; +- 其搜索性能等价于在关键字全集内做一次二分查找; +- 自动层次控制; + +## 2.B+TREE (**Mysql** 使用的默认索引结构) + +![image-20241018110218316](https://gitee.com/luo-zhouyi/note-sheet-bed/raw/master/text/img/upgit_20241018_1729220538.png) + +B+树的特征: + +所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的; +不可能在非叶子结点命中; +非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层; +每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。 +更适合文件索引系统; + +# 4.**索引分类** + +**MySQL 的索引有两种分类方式:逻辑分类和物理分类。** + +逻辑分类 +有多种逻辑划分的方式,比如按功能划分,按组成索引的列数划分等 + +## 按功能划分 + +- 主键索引:一张表只能有一个主键索引,不允许重复、不允许为 NULL; + + ```sql + ALTER TABLE TableName ADD PRIMARY KEY(column_list); + ``` + +- 唯一索引:数据列不允许重复,允许为 NULL 值,一张表可有多个唯一索引,索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。 + +- ```sql + CREATE UNIQUE INDEX IndexName ON `TableName`(`字段名`(length)); + # 或者 + ALTER TABLE TableName ADD UNIQUE (column_list); + ``` + +- 普通索引:一张表可以创建多个普通索引,一个普通索引可以包含多个字段,允许数据重复,允许 NULL 值插入; + + ```sql + CREATE INDEX IndexName ON `TableName`(`字段名`(length)); + # 或者 + ALTER TABLE TableName ADD INDEX IndexName(`字段名`(length)); + ``` + +# 二、作业 + +~~~sql +```sql +-- 准备数据 +create database if not exists db_view; +use db_view; + +# 部门表 +create table dept( + deptno int primary key, + dname varchar(20), + loc varchar(20) +); +insert into dept values(10, '教研部','北京'), +(20, '学工部','上海'), +(30, '销售部','广州'), +(40, '财务部','武汉'); + +# 员工表 +create table emp( + empno int primary key, + ename varchar(20), + job varchar(20), + mgr int, + hiredate date, + sal numeric(8,2), + comm numeric(8, 2), + deptno int, +-- FOREIGN KEY (mgr) REFERENCES emp(empno), + FOREIGN KEY (deptno) REFERENCES dept(deptno) ON DELETE SET NULL ON UPDATE CASCADE +); +insert into emp values +(1001, '甘宁', '文员', 1013, '2000-12-17', 8000.00, null, 20), +(1002, '黛绮丝', '销售员', 1006, '2001-02-20', 16000.00, 3000.00, 30), +(1003, '殷天正', '销售员', 1006, '2001-02-22', 12500.00, 5000.00, 30), +(1004, '刘备', '经理', 1009, '2001-4-02', 29750.00, null, 20), +(1005, '谢逊', '销售员', 1006, '2001-9-28', 12500.00, 14000.00, 30), +(1006, '关羽', '经理', 1009, '2001-05-01', 28500.00, null, 30), +(1007, '张飞', '经理', 1009, '2001-09-01', 24500.00, null, 10), +(1008, '诸葛亮', '分析师', 1004, '2007-04-19', 30000.00, null, 20), +(1009, '曾阿牛', '董事长', null, '2001-11-17', 50000.00, null, 10), +(1010, '韦一笑', '销售员', 1006, '2001-09-08', 15000.00, 0.00, 30), +(1011, '周泰', '文员', 1008, '2007-05-23', 11000.00, null, 20), +(1012, '程普', '文员', 1006, '2001-12-03', 9500.00, null, 30), +(1013, '庞统', '分析师', 1004, '2001-12-03', 30000.00, null, 20), +(1014, '黄盖', '文员', 1007, '2002-01-23', 13000.00, null, 10); + +# 工资等级表 +create table salgrade( + grade int primary key, + losal int, + hisal int +); +insert into salgrade values +(1, 7000, 12000), +(2, 12010, 14000), +(3, 14010, 20000), +(4, 20010, 30000), +(5, 30010, 99990); + +-- 练习和作业 +-- 1.给emp分别建立 普通索引和唯一索引 +-- 2.查询emp表有哪些索引 +-- 3. 使用有索引的字段进行查询,再查看这条语句是否使用到了索引。 +-- 4. 删除前面建立的两个索引 +-- 5. 选择两个字段添加一个复合索引 +-- 6. 使用复合索引的字段进行查询 +-- 作业 +-- 想办法用自己的电脑,生成500万行数据,id,uname,age 尽量随机,并记录时间。 +-- 1. 不用索引查询 一次姓名uname /并记录时间 +-- 2. 建立索引查询 一次姓名uname /并记录时间 + +``` +~~~ + +## 代码 + +```sql +-- 练习和作业 +-- 1.给emp分别建立 普通索引和唯一索引 + +CREATE INDEX index_job ON emp (sal); +CREATE UNIQUE INDEX index_ename ON emp (ename); + +-- 2.查询emp表有哪些索引 + +SHOW INDEX FROM emp; + +-- 3. 使用有索引的字段进行查询,再查看这条语句是否使用到了索引。 + +SELECT ename,sal FROM emp WHERE sal BETWEEN 10000 AND 20000; +EXPLAIN SELECT ename,sal FROM emp WHERE sal BETWEEN 10000 AND 20000; + +-- 4. 删除前面建立的两个索引 + +DROP INDEX index_job ON emp; +DROP INDEX index_ename ON emp; + +-- 5. 选择两个字段添加一个复合索引 + +CREATE INDEX index_eidjob ON emp (empno,job); + +-- 6. 使用复合索引的字段进行查询 + +SELECT * FROM emp WHERE empno > 1005 AND job = '文员'; +EXPLAIN SELECT * FROM emp WHERE empno > 1005 AND job = '文员'; + +-- 作业 +-- 想办法用自己的电脑,生成500万行数据,id,uname,age 尽量随机,并记录时间。 +-- 1. 不用索引查询 一次姓名uname /并记录时间 +-- 2. 建立索引查询 一次姓名uname /并记录时间 +``` + -- Gitee From 588a8949e191eb24d01416b9528a17b80d0cc621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=91=A8=E7=86=A0?= <2108439463@qq.com> Date: Mon, 21 Oct 2024 00:35:21 +0800 Subject: [PATCH 2/2] 10/21 --- .../24 20241018 \347\264\242\345\274\225.md" | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git "a/\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" "b/\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" index 43def55..29fc651 100644 --- "a/\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" +++ "b/\347\275\227\345\221\250\347\206\240/24 20241018 \347\264\242\345\274\225.md" @@ -186,6 +186,56 @@ EXPLAIN SELECT * FROM emp WHERE empno > 1005 AND job = '文员'; -- 作业 -- 想办法用自己的电脑,生成500万行数据,id,uname,age 尽量随机,并记录时间。 -- 1. 不用索引查询 一次姓名uname /并记录时间 + +CREATE TABLE test( +id int PRIMARY key auto_increment, +uname VARCHAR(10), +age int + +) + +CREATE PROCEDURE test1() +BEGIN + DECLARE number int; + DECLARE new_uname VARCHAR(10); + DECLARE new_age int; + + WHILE number < 10000 DO + + + SELECT CONCAT( + CHAR(FLOOR(RAND() * 26) + 65), -- 生成大写字母 A-Z + CHAR(FLOOR(RAND() * 26) + 65), + CHAR(FLOOR(RAND() * 26) + 65), + CHAR(FLOOR(RAND() * 26) + 65), + CHAR(FLOOR(RAND() * 26) + 65) +) into new_uname; + + + SELECT FLOOR(1 + (RAND() * 100)) into new_age ; + INSERT into test1(uname,age) VALUES(new_uname,new_age); + + set number=number+1; + + END WHILE; +END + + + +call test1() + + -- 2. 建立索引查询 一次姓名uname /并记录时间 + +CREATE index index_uname on test (uname) + +SELECT * FROM test WHERE uname='aa'; + + ``` +![image-20241021003254119](https://gitee.com/luo-zhouyi/note-sheet-bed/raw/master/imgs/202410210032298.png) + +![image-20241021003336382](https://gitee.com/luo-zhouyi/note-sheet-bed/raw/master/imgs/202410210033502.png) + +![image-20241021003352637](https://gitee.com/luo-zhouyi/note-sheet-bed/raw/master/imgs/202410210033719.png) -- Gitee