Java技术栈总结:数据库MySQL篇

一、慢查询

1、常见情形

聚合查询

多表查询

表数据量过大查询

深度分页查询

2、定位慢查询

方案一、开源工具

  • 调试工具:Arthas
  • 运维工具:Prometheus、Skywalking

方案二、MySQL自带慢日志

在MySQL配置文件 /etc/my.conf 中配置:

XML 复制代码
# 开启MySQL慢日志开关
slow_query_log=ON 
# 设置慢日志时间2秒,超过2秒的SQL语句会被认为是慢查询,记录慢查询日志 
long_query_time=2 
# 慢日志记录文件 
slow_query_log_file =/var/lib/mysql/localhost-slow.log

重启MySQL服务器,后续可在对应日志文件中查看慢日志信息。

3、慢SQL优化

  • 聚合查询,考虑增加临时表
  • 多表查询,优化SQL语句
  • 表数据量过大,增加索引
  • 深度分页查询,

其中,聚合查询、多表查询、数据量过大的情况,均可以使用SQL执行计划分析,进行优化。

sql 复制代码
EXPLAIN/DESC + 原SQL语句

字段含义

  • possible_key,当前SQL可能会使用到的索引;
  • key,当前SQL实际命中的索引;
  • key_len,索引"key"占用空间大小;
  • Extra,额外的优化建议;
    • Using where;Using index:使用了索引,需要的数据在索引中都能够找到,不需要回表查询。
    • Using index condition:使用了索引,但是需要回表查数据。
  • type,该SQL数据访问/操作的类型,性能从好到差依次为:NULL、system、const、eq_ref、ref、range、index、all。
    • ALL,扫描全部数据,MySQL将遍历全表以找到匹配的行;
    • index,遍历索引,索引树扫描;
    • range,索引范围查找;
    • ref,使用非唯一索引查找数据;
    • eq_ref,类似ref,区别是使用的索引为唯一索引,对于每个索引的键值,表中只有一条记录匹配。
    • const,根据主键查询;
    • system,查询mysql自带的表;

Q:某条SQL查询很慢,如何分析?

A:可以使用MySQL自带分析工具EXPLAIN。

  • 通过key和key_len检查是否命中了索引(索引本身存在是否有失效的情况)
  • 通过type字段查看sql是否有进一步的优化空间,是否存在全索引扫描或全盘扫描
  • 通过extra建议判断,是否出现了回表的情况,如果出现了,可以尝试添加索引或修改返回字段来修复

二、MySQL存储引擎

1、分类

存储引擎是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎基于表,而非基于数据库。

# 特性 MyISAM InnoDB MEMORY
事务 × ×
锁机制 表锁 表锁、行锁 表锁
外键 × ×

在mysql中提供了很多的存储引擎,比较常见有InnoDB、MyISAM、Memory

  • InnoDB存储引擎是mysql5.5之后是默认的引擎,它支持事务、外键、表级锁和行级锁
    • DML操作遵循ACID模型,支持事务;
    • 行级锁,提高并发性能;
    • 支持外键,FOREIGN KEY 约束,保证数据的完整及正确性。
  • MyISAM是早期的引擎,不支持事务、只有表级锁、也没有外键,用的不多
  • Memory主要把数据存储在内存,支持表级锁,没有外键和事务,用的也不多

2、体系结构

三、索引

索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构(**B+**),这些数据结构以某种方式指向数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

1、B树

2、B+树

MySQL的InnoDB引擎采用的B+树的数据结构来存储索引

  • 阶数更多,路径更短
  • 磁盘读写代价B+树更低,非叶子节点只存储指针,叶子阶段存储数据
  • B+树便于扫库和区间查询,叶子节点是一个双向链表(叶子节点内部为单向链表)。

B树与B+树对比:

①:磁盘读写代价B+树更低;②:查询效率B+树更加稳定;③:B+树便于扫库和区间查询

3、聚簇索引与非聚簇索引

聚簇索引,数据存储和索引在一块,索引结构的叶子节点保存了行数据。聚簇索引在每张表中都有且仅有一个。

非聚簇索引(二级索引),将数据与索引分开存储,叶子节点关联的内容为对应的主键。一张表可以有多个二级索引。

聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,将使用第一个唯一索引(UNIQUE)作为聚集索引。
  • 如果表没有主键,且没有合适的唯一索引,则InnoDB会++自动生成一个++++rowid++ 作为隐藏的聚集索引。

回表查询:通过二级索引找到对应的主键,然后根据主键值通过聚簇索引找到对应的行数据,这个查找的过程称为回表。

4、覆盖索引

覆盖索引:指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。

  • 使用id查询,直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。
  • 如果返回的列中没有创建索引,可能会触发回表查询,尽量避免使用select *

超大分页问题处理,

数据量较大的情况,使用 limit 分页查询,查询越靠后,查询效率越低。

优化思路:一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过 覆盖索引 + 子查询 的形式进行优化。

java 复制代码
select * from tb_sku t,
     (select id from tb_sku order by id limit 90000,10) a 
where t.id = a.id;

Q:超大分页怎么处理?

A:超大分页一般在数据量较大时,使用了limit分页查询,且需要对数据进行排序。这种情况下查询的效率就会比较低,可以采用覆盖索引和子查询解决。

首先,分页查询数据的主键id字段,然后用子查询来过滤,只需要查询这个id列表中的数据即可。因为查询id的时候走的是覆盖索引,所以效率会提升。

相关推荐
不想画图6 小时前
数据库基础操作和权限管理
数据库·mysql
没有bug.的程序员6 小时前
GC日志解析:从日志看全流程
java·网络·jvm·spring·日志·gc
WZTTMoon6 小时前
开发中反复查的 Spring Boot 注解,一次性整理到位
java·spring boot·后端
如果未来,6 小时前
Oracle数据库的存储结构以及表空间的概念
数据库·oracle
葡萄城技术团队6 小时前
Excel 文件到底是怎么坏掉的?深入 OOXML 底层原理讲解修复策略
android·java·excel
照物华6 小时前
MySQL 软删除 (Soft Delete) 与唯一索引 (Unique Constraint) 的冲突与解决
java·mysql
清涧游6 小时前
第九章-NOP团队dmz-A
笔记·学习·安全
mjhcsp6 小时前
C++ 后缀自动机(SAM):原理、实现与应用全解析
java·c++·算法
sensen_kiss6 小时前
INT303 Big Data Analysis 大数据分析 Pt.10 分析模型和混合模型
大数据·学习·机器学习·数据挖掘·数据分析
QiZhang | UESTC6 小时前
学习日记day41
学习