我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL优化(3):索引

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL优化(3):索引

MySQL优化(3):索引

MySQL优化中,最重要的优化手段就是索引,也是最常用的优化手段

 

索引简介:

索引:关键字与数据位置之间的映射关系

关键字:从数据中提取,用于标识,检索数据的特定内容

目的:加快检索

 

索引检索为什么快:

(1)关键字相对于数据本身,量较小

(2)关键字都是排序好的

 

MySQL中索引的类型:

普通索引,唯一索引,主键索引,全文索引

不同的类型只是对关键字的限制不同

普通索引:多索引关键字没限制,有长度限制

唯一索引:要求记录提供的关键字不能重复

主键索引:要求关键字不能重复而且不能为NULL

全文索引:不支持中文,后续细讲

 

索引的语法:

查看索引:

SHOW CREATE TABLE [table-name];

 比如查到PRIMARY KEY(‘id’),就是一个主键索引

 

创建索引:需要修改表结构和创建表时候完成,基于不同的类型,方式也不同

同时创建四个索引,由于使用到了全文索引,这里使用MYISAM引擎

CREATE TABLE USER(
ID INT AUTO_INCREMENT PRIMARY KEY,
FIRST_NAME VARCHAR(16),
LAST_NAME VARCHAR(16),
SN VARCHAR(16),
INFORMATION TEXT,
KEY(FIRST_NAME,LAST_NAME),
UNIQUE KEY(SN),
FULLTEXT KEY(INFORMATION)
)ENGINE=MYISAM;

索引可以命名,比如KEY NAME (FIRST_NAME,LAST_NAME)

这句话创建了一个基于FIRST_NAME和LAST_NAME的复合普通索引

UNIQUE KEY(SN) 创建了基于SN的唯一索引,默认以字段名命名索引

最后一个全文索引很鸡肋,基本不会用

 

在修改表结构的时候创建索引:

ALTER TABLE USER(
ADD KEY(FIRST_NAME,LAST_NAME),
ADD UNIQUE KEY(SN),
ADD FULLTEXT KEY(INFORMATION)
)

 

删除索引:

ALTER TABLE [table-name] DROP PRIMARY KEY;
ALTER TABLE [table-name] DROP KEY [key-name];

一般不简易删除主键索引,记录是按照主键来排序的,设计主键要注意一定与业务逻辑无关

 

执行计划:

执行计划:当MySQL执行SQL语句时,会分析、优化、形成执行计划后按照执行计划来执行

在执行计划中可以清楚的看到当前的查询是否需要用到索引:

EXPLAIN SELECT * FROM [table-name] WHERE ID<20;

结果中有一样:KEY:PRIMARY,代表该查询语句会用到主键索引

 

索引使用的场景:

如果两张表,学生和班级表,多对一的关系,导入较多的记录来测试

(1)WHERE查询

EXPLAIN SELECT * FROM STUDENT WHERE ID=123456

和上面的例子一样,可以看到使用到了主键索引

EXPLAIN SELECT * FROM STUDENT WHERE USERNAME="XXX"

这句话执行后会发现:KEY:NULL,没有索引

我们给它加上索引:(这里的INDEX和上文的KEY都可以)

ALTER TABLE STUDENT ADD INDEX (USERNAME);

查看执行计划后可以发现:KEY:USERNAME,说明使用到了新建的索引

 

(2)ORDER BY排序

我们有可能会遇到以下的情况:

SELECT * FROM STUDENT ORDER BY USERNAME;

查看执行计划后可以发现没有使用到任何索引,并且看到了Extra:Using Filesort,使用到了外部文件排序,性能更低,需要先将数据读取到内存,分段读取合并排序

提高效率的方式是增加索引:

ALTER TABLE STUDENT ADD INDEX (USERNAME);

现在查看执行计划后,可以发现使用到了USERNAME索引,并且没有使用外部文件排序,性能会有明显提升

 

(3)JOIN 连接

使用到这条语句:

SELECT C.* COUNT(S.ID) FROM CLASS C JOIN STUDENT S ON C.ID=S.CLASS_ID GROUP BY C.ID;

当数据量巨大的时候,这句话要执行5S以上

查看执行计划后,发现其中一张表没有索引,且使用到了外部文件排序

解决:

ALTER TABLE STUDENT ADD INDEX (CLASS_ID);

执行后发现速度明显提升,并且两张表都使用到了索引,没有外部文件排序

 

(4)索引覆盖

前三条很重要,是必须做的优化,这条只是一个现象

比如我们使用这条语句:建立一个复合索引

ALTER TABLE STUDENT ADD INDEX (FIRSTNAME,LASTNAME);

然后再执行:这句话没有使用到以上三种情况

SELECT FIRSTNAME,LASTNAME FROM STUDENT;

但是查看计划后,发现还是使用到了索引,并且Extra:Using index,说明这句话只使用了索引来完成

如果执行这句话

SELECT FIRSTNAME,LASTNAME,USER FROM STUDENT;

再查看计划后发现没有使用到了索引,并且进行了全表扫描

两次的差异只是多了一个USER字段,而复合索引没有包含该字段

 

总结:MySQL的查询优先使用了索引,由于索引覆盖,建议SELECT后面只写有必要的字段,被覆盖的可能性就会提升,尽可能地优化

 

语法注意细节:

(1)字段需要独立出现

SELECT * FROM STUDENT WHERE ID+1=20;

这句话是能执行成功的,ID是主键,查看计划后却没有使用到主键索引

字段没有独立出现,不能触发该字段上的索引,避免这种情况

(2)LIKE查询不能以通配符开头

SELECT * FROM STUDENT WHERE USERNAME LIKE "%A%";

这句话无法使用到索引,如果是以下的情况,那么会用到索引

SELECT * FROM STUDENT WHERE USERNAME LIKE "A%";

字符串比较中,不能使用包含的逻辑,比如查询包含Java的字符串,不能写"%Java%",效率过低

解决办法:全文索引,但是MySQL全文索引很鸡肋,应该使用第三方的比如ES,Solr

(3)复合索引的右侧字段不能独立使用索引

已有INDEX NAME(FIRSTNAME,LASTNAME);

使用语句,这句话使用到了索引

SELECT * FROM STUDENT WHERE FIRSTNAME="XXX";

而下面这句话没有使用到索引

SELECT * FROM STUDENT WHERE LASTNAME="XXX";

原因:复合索引是按照左侧字段排序的,如果左侧字段相同再用右侧字段排序,总体上来看,右侧字段是未排序的

既然这样为什么还要建复合索引呢?以下这种情况

SELECT * FROM STUDENT WHERE FIRSTNAME LIKE "XX%" AND LASTNAME LIKE "XX%";

这句话如果建立两个索引,那么计算两个索引的交集会更慢,所以需要复合索引

如果遇到上面的情况,再给LASTNAME建立一个索引即可

(4)早期版本NULL值无法使用索引

SELECT * FROM STUDENT WHERE FIRSTNAME=NULL;

新版本无需关心这一条

(5)OR语法保证两边的条件都有索引可用

SELECT * FROM STUDENT WHERE FIRSTNAME LIKE "XX%" OR USER LIKE "XX%";

如果USER没有索引,那么还是会全表查询

(6)状态值不容易使用到索引

GENDER 0,1,2表示男,女,未知

即使在字段上增加了索引,通常也不会起作用

SELECT * FROM STUDENT WHERE GENDER IN (0,1);

 原因:状态值往往导致一个状态值匹配大量记录,查询大量记录的时候,MYSQL认为使用索引开销比全表扫描都要大

 

如何创建索引:

(1)WHERE,ORDER BY,JOIN字段上建立索引

(2)组合索引的建立:基于业务逻辑

(3)如果条件经常出现在一起,多字段索引可以升级为复合索引

(4)如果通过增加个别字段,就可以出现索引覆盖,那么增加个别字段

(5)不会用到的索引应该删掉

(6)常规情况下我们建立的数据库系统本身性能就不差了

(7)有些字段是否只使用前缀就能完成,使用前缀索引

 

前缀索引:INDEX(FIELD(10))

使用字段field的前10个字符建立索引,默认是使用字段全部内容建立索引

使用:GIT的COMMIT_ID;密码字段

 

索引的存储结构:

BTREE索引,HASH索引,聚簇索引

以上概念指的是索引的存储结构,数据结构上的概念,实际使用无需关心,了解即可

 

BTREE索引:

索引存储在磁盘上所用的基础的通用的存储结构

特征:磁盘上的数据结构,不是二叉树,一定要一个中文,那就是多路平衡查找树

特点:一个BTREE节点,存储多个索引关键字,多少由节点大小和关键字来确定的,

节点大小是固定的,由计算机文件系统来确定,一次性磁盘读取内存量,就是一个节点大小

由于一个节点的大小是固定的,一个节点无法容纳大量关键字,所以分散在多个节点来存储关键字

这时候如何进行排序呢?通过上层节点的子节点指针指向下层节点,用来关联所有的节点,子节点指针位于关键字之间

 

例如每个节点存储1000个关键字,深度为2的两层BTREE大概可以存储1000000(1000*1000)个关键字

查找一个关键字,需要读取几个节点的内容呢?从根开始,确定下级节点,仅仅两次的磁盘读取就可以做到

Btree的意义在于可以遍历大量关键字,减少磁盘读取量的开销

 

聚簇索引:

关键字和记录在一起进行存储

是升级后的Btree,数据结构上的B+Tree

MySQL中只有Innodb的主键索引是聚簇结构

 

HASH索引:

当索引被载入到内存后采用的存储结构,采用哈希结构存储了,类似Java的Map,Key-Value

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MySQL优化(3):索引

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MySQL优化(3):索引

MySQL优化中,最重要的优化手段就是索引,也是最常用的优化手段 索引简介:索引:关键字与数据位置之间的映射关系关键字:从数据中提取,用于标识,检索数据的特定内容目的:加快检索 索引检索为什么快:(1)关键字相对于数据本身,量较小(2)关键字都是排序好的 My
MySQL优化(3):索引
2014-05-17

MySQL索引优化

一、单表创建索引之前:type=ALL全表扫描,Extra里面的Using filesort(文件内部排序)根据where后面的条件创建:CREATE INDEX idx_article_ccv ON article(category_id,comments,
MySQL索引优化
2019-01-06

MySQL索引优化EXPLAIN

日常在CURD的过程中,都避免不了跟数据库打交道,大多数业务都离不开数据库表的设计和SQL的编写,那如何让你编写的SQL语句性能更优呢? 先来整体看下MySQL逻辑架构图: MySQL整体逻辑架构图可以分为Server和存储引擎层。 Server层: Ser
MySQL索引优化EXPLAIN
2015-10-24

MySQL优化之索引

SQL为什么需要优化?对于初学者来说,能够写出实现功能的SQL语句而不出错,查询出所需要的结果,就已经能够满足日常使用了。但在某些场景,对性能的要求比较高,因此,要求SQL的执行响应速度快,就需要对SQL进行一定程度的优化。在实际应用场景中,MySQL经常会存
MySQL优化之索引
2021-02-14

MySQL索引优化深入

创建 test 测试表CREATE TABLE `test` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `c1` varchar(10) DEFAULT NULL,  `c2` varchar(10) DEFAULT 
MySQL索引优化深入
2016-11-27

MySQL 索引优化案例

目录数据准备联合索引的首字段用范围查询强制走索引覆盖索引优化in和or什么时候会走索引like xx% 一般都会走索引,和数据量无关索引下推为什么范围查找没有用索引下推优化?如何选择索引Trace 工具深入优化order by 和 grou
2022-08-19

MySQL如何优化索引

1. MySQL如何使用索引 索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后遍历整个表以找到相关的行。表越大,花费越多。如果表中有相关列的索引,MySQL可以快速确定要在数据文件中间查找的位置,而不必查看
2022-05-27

mysql索引怎么优化

1. 使用合适的数据类型:选择合适的数据类型可以减小索引的大小,提高查询速度。例如,使用INT类型代替VARCHAR类型存储数字字段。2. 选择合适的索引列:在创建索引时,选择最常被查询的列作为索引列,可以提高查询速度。避免创建过多的索引,
mysql索引怎么优化
2024-02-29

MySQL索引优化分享

2,explain的作⽤ 查看表的读取顺序,读取操作类型,有哪些索引可用,表之间关联,每张表中有哪些索引被优化器执⾏3,索引命中策略略分析    最左匹配原则 在索引字段上加入函数(不匹配索引)    is null/is not null/not in(不匹
MySQL索引优化分享
2016-09-28

MySQL性能优化,MySQL索引优化,order by优化,explain优化

今天我们来讲讲如何优化MySQL的性能,主要从索引方面优化。

MySQL索引优化Linux案例

在MySQL中,索引是一种优化数据库表查询的技朮。通过为查询字段创建索引,可以大大提高数据检索的速度。下面是一个在Linux环境下优化MySQL索引的案例:登录MySQL数据库:mysql -u root -p查看当前数据库中的表和索引:S
MySQL索引优化Linux案例
2024-08-16

MySQL优化之索引解析

索引的本质MySQL索引或者说其他关系型数据库的索引的本质就只有一句话,以空间换时间。索引的作用索引关系型数据库为了加速对表中行数据检索的(磁盘存储的)数据结构索引的分类数据结构上面的分类HASH 索引等值匹配效率高不支持范围查找树形索引二叉树,递归二分查找法
MySQL优化之索引解析
2019-07-07

编程热搜

目录