1 索引语法
-
创建索引
CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name(index_column_name,...);
- Index_name:规范为
idx_表名_字段名...
- Index_name:规范为
-
查看索引
SHOW INDEX FROM table_name;
-
删除索引
DROP INDEX index_name ON table_name;
按照下列要求,创建索引:
- name字段为姓名字段,该字段值可能重复,为该字段创建索引;
- phone手机号字段值,要求非空且唯一,为该字段创建唯一索引;
- 为profession、age、status创建联合索引;
- 为email索引建立合适的索引来提升查询效率。
首先查看下表tb_user1当前索引,如下图1-2所示:
name字段建立常规索引,sql如下:
CREATE INDEX idx_tb_user1_name ON tb_user1(name);
给字段phone创建唯一索引,sql如下:
CREATE UNIQUE INDEX idx_tb_user1_phone ON tb_user1(phone);
为profession、age、status创建联合索引,sql如下:
CREATE INDEX idx_tb_user1_pro_age_sta ON tb_user1(profession, age, phone);
- 联合索引字段顺序由讲究
- seq_in_index:该索引(联合索引)字段顺序
为提高查询效率,为email字段建立常规索引,sql如下:
CREATE INDEX idx_tb_user1_email ON tb_user1(email);
在此查看tb_user1表中的索引如下图1-3所示:
删除idx_tb_user1_email索引,sql如下:
DROP INDEX idx_tb_user1_email ON tb_user1;
2 性能分析
2.1 查看执行频次
通过如下命令,可以查看当前数据库INSERT,UPDATE,DELETE,SELECT的访问频次
SHOW GLOBAL|SESSION STATUS LIKE 'Com_______'
如下图2.1-1所示:
-
Com后面跟7个下划线
-
通过该指令确认当前数据库是查询为主还是增、删或者改为主,然后针对不同类型做相应的优化。
2.2 慢查询日志
MySQL慢查询日志是MySQL数据库的一项功能,用于记录执行时间超过预设阈值的查询语句。慢查询日志可以帮助你识别数据库性能瓶颈和优化查询语句。
要启用MySQL慢查询日志,你可以按照以下步骤进行操作:
-
打开MySQL配置文件(通常是my.cnf或my.ini)。你可以在MySQL的安装目录中找到该文件。
-
在配置文件中找到
[mysqld]
部分,如果不存在,请添加该部分。 -
在
[mysqld]
部分下添加或修改以下行,以启用慢查询日志:slow_query_log = 1 // 启用慢查询日志 slow_query_log_file = /path/to/slow-query.log // 慢查询日志文件的路径和名称 long_query_time = 1 // 查询执行时间超过多少秒将被记录到慢查询日志中
注意,你需要根据实际情况设置适当的路径和时间阈值。
-
保存并关闭配置文件。
-
重启MySQL服务器,以使配置更改生效。
现在,MySQL将开始记录执行时间超过指定阈值的查询语句到慢查询日志文件中。你可以使用任何文本编辑器打开日志文件以查看其中的查询语句和执行时间。
另外,你也可以使用MySQL提供的工具来分析慢查询日志,例如mysqldumpslow和pt-query-digest。这些工具可以帮助你解析慢查询日志文件并生成汇总报告,以便更好地理解数据库性能问题。
需要注意的是,启用慢查询日志会对系统性能产生一定的影响,因为它需要记录大量查询信息。因此,在生产环境中,你可能需要谨慎使用慢查询日志功能,并根据需要进行开关控制。
示例:
Time Id Command Argument
# Time: 2023-06-12T00:28:49.903565Z
# User@Host: root[root] @ [172.17.0.1] Id: 8
# Query_time: 2.961605 Lock_time: 0.000026 Rows_sent: 1 Rows_examined: 0
use gaogzhen;
SET timestamp=1686529726;
select count(*) from tb_sku;
- 记录当前时间、登录用户、主机、查询用时、加锁时间、查询那个数据库、时间、执行语句等
- 慢查询日志一般在开发测试环境中使用,生成环境慎用。
2.3 profile
MySQL的profile是一种功能,用于分析查询的性能和资源消耗情况。通过启用profile,你可以获得关于每个查询的详细信息,包括执行时间、扫描的行数、使用的临时表等等。这对于优化查询和发现潜在的性能问题非常有用。
要使用MySQL的profile功能,你可以按照以下步骤进行操作:
-
打开MySQL客户端,以管理员或具有适当权限的用户身份登录到MySQL服务器。
-
在执行查询之前,使用以下命令启用profile功能:
SET profiling = 1;
这将启用profile功能,并将性能信息记录到MySQL服务器的内存中。
-
执行你想要分析的查询语句。
-
当查询完成后,使用以下命令查看profile结果:
SHOW PROFILES;
这将显示所有执行过的查询的列表,包括每个查询的标识符和执行时间。
示例截图如下图2.3-1所示:
-
选择你想要查看详细信息的查询,使用以下命令查看该查询的profile结果:
SHOW PROFILE FOR QUERY <query_id>;
将
\<query_id>
替换为你要查看的查询的标识符。 -
这将显示该查询的详细profile结果,包括每个阶段的耗时、扫描的行数、使用的临时表等。
注意,使用完profile功能后,应使用以下命令禁用profile功能,以避免对性能产生额外的开销:
SET profiling = 0;
MySQL的profile功能对于优化查询和发现性能问题非常有用,但在生产环境中使用时应谨慎,以避免对系统性能造成过大的影响。
2.4 explain
2.4.1 概述
EXPLAIN是MySQL提供的一个关键字,用于分析查询语句的执行计划。通过EXPLAIN,你可以获取关于查询语句的详细信息,包括查询的表、使用的索引、连接类型、扫描行数等等。这些信息对于优化查询和理解查询性能非常有帮助。
要使用EXPLAIN,你可以按照以下步骤进行操作:
-
打开MySQL客户端,以管理员或具有适当权限的用户身份登录到MySQL服务器。
-
在客户端中,使用以下语法来执行EXPLAIN并分析查询语句:
EXPLAIN your_query;
将"your_query"替换为你要分析的查询语句。
-
执行上述命令后,MySQL将返回一个关于查询执行计划的结果集,包含多列的信息,如下所示:
- id: 查询的唯一标识符,用于区分不同的查询。
- select_type: 查询类型,包括简单查询、联接查询、子查询等。
- table: 查询涉及的表名。
- partitions: 查询涉及的分区。
- type: 表访问的类型,如全表扫描、索引扫描等。
- possible_keys: 可能使用的索引。
- key: 实际使用的索引。
- key_len: 使用的索引长度。
- ref: 列与索引之间的关联。
- rows: 预计扫描的行数。
- filtered: 通过条件过滤的行占比。
- Extra: 其他额外的信息,如是否使用了临时表、使用的排序方式等。
这些列提供了关于查询执行计划的详细信息,你可以根据这些信息来优化查询语句,例如选择更合适的索引、优化连接方式等。
通过使用EXPLAIN,你可以更好地理解查询语句的执行方式,并进行性能优化。这对于大型数据库和复杂查询尤为重要。
示例有student,course,student_course三张表,学生表与课程表直接通过学生选课表多对多关联。
2.4.2 重点解析
- id :select 查询的序列号,表示查询中执行select子句或者操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行);
示例:
-
查看所有学生选课情况执行计划
- sql语句
explain select s.*, c.* from student s, course c, student_course sc where s.id = sc.studentid and sc.courseid = c.id;
- 查询结果
- id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE s ALL PRIMARY 4 100.00
1 SIMPLE sc ALL fk_courseid,fk_studentid 6 33.33 Using where; Using join buffer (hash join)
1 SIMPLE c eq_ref PRIMARY PRIMARY 4 gaogzhen.sc.courseid 1 100.00
-
查询选修了MYSQL课程的学生信息(子查询)
-
explain select * from student s where s.id in ( select studentid from student_course sc where sc.courseid = ( select id FROM course c where c.NAME = 'MYSQL' ) );
-
id select_type table
1 PRIMARY
1 PRIMARY s
2 MATERIALIZED sc
3 SUBQUERY c
-
-
type: 表示连接类型,性能有好到差的连接类型为NULL、system、const、eq_ref、ref、range、index、all。
-
优化原则尽量向前优化;
-
NULL:不访问任何表,比如
select 1;
-
system:使用系统表;
-
const:使用主键或者唯一索引;
-
ref:使用非唯一索引;
-
All:全表扫描,性能很低。
结语
如果小伙伴什么问题或者指教,欢迎交流。
❓QQ:806797785
参考链接:
[1]MySQL数据库视频[CP/OL].2020-04-16.p74-78.