diff --git "a/58 \351\231\210\350\203\234\346\235\260/2023-10-18.md" "b/58 \351\231\210\350\203\234\346\235\260/2023-10-18.md" new file mode 100644 index 0000000000000000000000000000000000000000..fb974297866d28963143a8fe63a007300e2472b5 --- /dev/null +++ "b/58 \351\231\210\350\203\234\346\235\260/2023-10-18.md" @@ -0,0 +1,155 @@ +## 笔记 + +- 官方上面说索引是帮助MySQL`高效获取数据`的`数据结构`,通俗点的说,数据库索引好比是一本书的目录,可以直接根据页码找到对应的内容,目的就是为了`加快数据库的查询速度`。 +- 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。 +- 一种能帮助mysql提高了查询效率的数据结构:**索引数据结构**。 + +## 1.1、索引原理 + +索引的存储原理大致可以概括为一句话:**以空间换时间**。 + +一般来说索引本身也很大,不可能全部存储在内存中,因此`索引往往是存储在磁盘上的文件中的`(可能存储在单独的索引文件中,也可能和数据一起存储在数据文件中)。 + +数据库在未添加索引进行查询的时候默认是进行全文搜索,也就是说有多少数据就进行多少次查询,然后找到相应的数据就把它们放到结果集中,直到全文扫描完毕。 + +## 1.2、索引的分类 + +**主键索引:`primary key`** + +- 设定为主键后,数据库自动建立索引,InnoDB为聚簇索引,主键索引列值不能为空(Null)。 + +**唯一索引:** + +- 索引列的值必须唯一,但允许有空值(Null),但只允许有一个空值(Null)。 + +**复合索引:** + +- 一个索引可以包含多个列,多个列共同构成一个复合索引。 + +**全文索引:** + +- Full Text(MySQL5.7之前,只有MYISAM存储引擎引擎支持全文索引)。 +- 全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找允许在这些索引列中插入重复值和空值。全文索引可以在**Char、VarChar** 上创建。 + +**空间索引:** + +- MySQL在5.7之后的版本支持了空间索引,而且支持OpenGIS几何数据模型,MySQL在空间索引这方年遵循OpenGIS几何数据模型规则。 + +**前缀索引:** + +- 在文本类型为char、varchar、text类列上创建索引时,可以指定索引列的长度,但是数值类型不能指定。 + +## 1.3、索引的优缺点 + +**优点:** + +- 大大提高数据查询速度。 +- 可以提高数据检索的效率,降低数据库的IO成本,类似于书的目录。 +- 通过索引列对数据进行排序,降低数据的排序成本降低了CPU的消耗。 +- 被索引的列会自动进行排序,包括【单例索引】和【组合索引】,只是组合索引的排序需要复杂一些。 +- 如果按照索引列的顺序进行排序,对order 不用语句来说,效率就会提高很多。 + +**缺点:** + +- 索引会占据磁盘空间。 +- 索引虽然会提高查询效率,但是会降低更新表的效率。比如每次对表进行增删改查操作,MySQL不仅要保存数据,还有保存或者更新对应的索引文件。 +- 维护索引需要消耗数据库资源。 + +**综合索引的优缺点:** + +- `数据库表中不是索引越多越好,而是仅为那些常用的搜索字段建立索引效果最佳!` + +- ## 1.4、创建索引的基本操作 + + **创建主键索引:** + + ``` + #建表时,主键默认为索引 + create table user( + id varchar(11) primary key, + name varchar(20), + age int + ) + + #查看user表中的索引 + show index from user; + ``` + + **创建单列索引:** + + ``` + #创建单列索引,只能包含一个字段 + create index name_index on user(name); + ``` + + **创建唯一索引:** + + ``` + #创建唯一索引,只能有一个列 + create unique index age_index on user(age); + ``` + + **创建符合索引:** + + ``` + #复合索引 + create index name_age_index on user(name,age); + ``` + + **满足复合索引的查询的两大原则:** **假如创建的复合索引为三个字段,按顺序分别是(name,age,sex) 在查询时能利用复合索引的查询条件如下:** + + - 1、最左前缀原则(如下四种都满足条件) + + ``` + select * from user where name = ? + select * from user where name = ? and age = ? + select * from user where name = ? and sex = ? + select * from user where name = ? and age = ? and sex = ? + ``` + + - 1.1、如下是不满足最前左缀的条件(但是不是全部都不生效,如下第2原则解释) + + ``` + select * from user where name = ? and sex = ? and age = ? + select * from user where age = ? and sex = ? and name = ? + select * from user where sex = ? and age = ? and name = ? + select * from user where age = ? and sex = ? + …………等等 + ``` + + - 2.MySQL 引擎在执行查询时,为了更好地利用索引,在查询过程中会动态调整查询字段的顺序!**(也就是说,当条件中的字段全部达到复合索引中的字段时,可以动态调整字段顺序,使其满足最前左缀)** + + ``` + #可以使用复合索引:索引中包含的字段数都有,只是顺序不正确,在执行的时候可以动态调整为最前左缀 + select * from user where sex = ? and age = ? and name = ? + select * from user where age = ? and sex = ? and name = ? + + #不可以使用复合索引:因为缺少字段,并且顺序不正确 + select * from user where sex = ? and age = ? + select * from user where age = ? and name = ? + select * from user where age = ? + select * from user where sex = ? + ``` + +## 作业 + + + +屏幕截图 2023-10-19 070242 + +~~~ mysql +-- --案例 +-- 执行查询文件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; + +~~~ \ No newline at end of file