秋招Day14 - MySQL - SQL优化

什么是慢SQL?

MySQL中有一个叫做long_query_time的参数,如果SQL的执行时间超过这个参数,就是慢SQL,会被记录到慢查询日志中。

如何优化慢SQL?

通过慢查询日志找到慢SQL,使用EXPLAN查看慢SQL的执行计划,看看有没有索引,大部分情况下都是因为没有索引导致慢SQL。或者可以优化查询条件、减少返回字段等方式进行优化。

慢SQL日志怎么开启?

编辑mysql配置文件my.inf,将slow_query_log设置为1,也可以通过SET GLOBAL命令动态设置

你知道哪些方法优化SQL?

尽可能的少扫描、尽快地返回结果

加索引,比如覆盖索引、让联合索引遵循左前缀原则。

如何利用覆盖索引?

覆盖索引就是查询所需的字段都在同一个索引里 ,这样mysql就不需要回表,直接从索引中返回结果。

在实际使用中,我会优先考虑把SELECT涉及的字段和WHERE涉及的查询条件一起建立联合索引,并通过EXPLAIN检查是否USING INDEX,确认命中索引

如何正确使用联合索引?

要遵循左前缀原则,也就是说查询条件需要包含索引最左侧字段。

如何进行分页优化?

分页优化是为了避免偏移量过大带来的全表扫描,可以通过延迟关联添加书签来解决。

延迟关联是先通过索引快速定位到所需要的主键id,然后再通过主键id关联其他表获取所需要的完整行数据,减少初始数据加载量并避免回表

原SQL:

sql 复制代码
SELECT e.id, e.name, d.details
FROM employees e
JOIN department d ON e.department_id = d.id
ORDER BY e.id
LIMIT 1000, 20;

优化后,第一步只查主键,速度快,第二步只处理 20 条数据,效率高:

sql 复制代码
SELECT e.id, e.name, d.details
FROM (
    SELECT id
    FROM employees
    ORDER BY id
    LIMIT 1000, 20
) AS sub
JOIN employees e ON sub.id = e.id
JOIN department d ON e.department_id = d.id;

添加书签的方式是记住上一次查询返回的最后一行主键值,下一次查询的时候直接从这个主键值开始,不再使用OFFSET

sql 复制代码
SELECT id, name
FROM users
WHERE id > last_max_id  -- 假设last_max_id是上一页最后一行的ID
ORDER BY id
LIMIT 20;

分页查询为什么会变慢?

因为每次查询都要从第一条数据开始,随着OFFSET的主键增大,要扫描并跳过的数据越来越多

JOIN代替子查询有什么好处?

JOIN的ON条件能够更直接地触发索引,而子查询可能会因为嵌套查询而导致索引失效

JOIN的一次性连接操作替代了子查询的多次重复执行,在数据量大的情况下性能差距明显

JOIN操作为什么要小表驱动大表?

第一,如果大表有索引,小表的每一行都可以通过索引快速匹配大表的相应行。

第二,如果大表没有索引,需要将小表的数据加载到内存,然后全表扫描大表做匹配,这样做比用大表做驱动时时间复杂度更小

为什么要避免用JOIN关联过多的表?

第一,多表JOIN的执行路径会随着表的数量呈现指数级增长,优化器需要估算所有路径的成本

第二,多表JOIN需要缓存中间结果集,中间结果集占用内存过多的话可能会从内存转移到磁盘,性能急剧下降

如何进行排序优化?

  • ORDER BY涉及的字段添加索引,避免file sort,使用联合索引时需与ORDER BY 顺序一致
  • 可以适当修改排序参数,比如增大sort_buffer_size, max_length_for_sort_data等,让排序在内存中完成
  • 可以使用WHERELIMIT来限制需要排序的数据量,减少排序开销。

什么是filesort?

不能利用索引的天然有序性生成排序结果的时候,MySQL需要自己进行排序,如果数据量比较小,会在内存中进行,但是如果数据量比较大就需要写临时文件到磁盘再排序,这叫filesort

全字段排序和rowid排序了解多少?

无法使用索引排序时,MySQL需要在内存中或者磁盘中进行操作,分为全字段排序和rowid排序

  • 全字段排序会一次性取出满足条件行的记录的所有SELECT字段,然后在 sort buffer 中进行排序,排序后直接返回结果,无需回表。优点是只需要进行一次I/O,缺点是内存占用过大,可能会导致filesort
  • rowid排序是只取出主键id和排序字段,存入sort buffer中进行排序,根据排序后的主键id回表取出其他需要的字段。优点是内存占用小,缺点是I/O需要两次。

SELECT + ORDER BY字段的最大长度 <= max_length_for_sort_data, MySQL采用全字段排序避免回表;反之,采用rowid排序避免内存占用过大导致的filesort

Sort_merge_passes参数了解吗?

排序的数据量超过sort_buffer_size时,排序无法完全在内存中进行,MySQL就会使用临时文件进行外部排序,这个时候就会产生Sort_merge_passes这个状态变量,如果这个状态变量短时间内快速激增,代表排序操作的数据量过大,这时需要调整sort_buffer_size的大小。

MySQL执行排序时有两个阶段:

一、内存排序阶段:首先尝试在sort_buffer中进行快速排序。

二、外部排序阶段:如果需要排序的数据量超过sort_buffer_size,MySQL会将数据分割为多个块,每块单独在内存中排序后写入临时文件,然后对这些已排序的块进行归并排序。每次归并操作都会增加Sort_merge_passes的值

条件下推你了解多少?

条件下推是将外层的过滤条件,比如WHERE,JOIN等,尽可能的下推到查询计划的更底层,比如说子查询,连接操作之前,以**减少中间结果的数据量,**避免外部过滤。

为什么要尽量避免使用SELECT *?

加载冗余数据会占用更多的缓存空间,从而挤占其他重要数据的缓存资源,降低整体系统的吞吐量。

也会增加网络传输的开销,尤其是在大字段的情况下。

最重要的是,SELECT * 可能会导致覆盖索引失效,本来可以直接走索引的查询可能会需要回表

你还知道哪些SQL优化的方法?

避免使用!=或<>操作符

!=和<>操作符是等价的,应该避免使用,因为这会导致MySQL无法使用索引,从而导致全表扫描

可以改成使用column>'aaa' or column<'aaa'

使用前缀索引

比如邮箱从@开始的后几位都是固定的,就可以只对前缀建立索引

sql 复制代码
alter table test add index index2(email(6));

前缀索引不能用于GROUP BY和ORDER BY

避免在where中对列使用函数

会导致索引失效,因为MySQL会对每列应用函数之后在进行比较

EXPLAIN平常有用过吗?

经常用,explain 是 MySQL 提供的一个用于查看 SQL 执行计划的工具,可以帮助我们分析查询语句的性能问题。

一共有十多个输出参数:

比如说type = ALL,key = NULL,就代表全表扫描,这时应该对WHERE语句中的列加索引。

extra = using filesort代表不能使用索引完成排序,可考虑对ORDER BY的字段加索引

常见字段含义了解吗?

type、key、row和extra。

通过它们判断SQL有没有走索引、是否全表扫描、预估扫描行数是否过大、是否触发了filesort或临时表

type的执行效率等级达到什么级别比较合适?

由高到底是system(表只有一行,系统表)、const、eq_ref、ref、range、index(扫描索引的**所有叶子节点)**和ALL(全表扫描)

一般情况下建议达到const(唯一索引,返回一行结果),eq_ref(多表连接中,通过索引,对每个前表的行,后表最多匹配一行)或ref(非唯一索引),涉及到范围查询到话range也可以。

相关推荐
Web Security Loop4 分钟前
MAC卸载JDK环境
java·macos·jdk
NiceCloud喜云24 分钟前
腾讯云国际版云数据库选型:MySQL、Redis 怎么按业务架构来判断
数据库·mysql·腾讯云
ew4521833 分钟前
MySQL JOIN 关联语法、差异、标准用法、经典坑点汇总
数据库·mysql
Rain的Java大神之路1 小时前
线上接口负载满了如何解决
java·数据库·redis·后端·缓存·面试·架构
Nturmoils1 小时前
给运营导个 CSV,在 ksql 里用 \copy 就够了
数据库
ciqingloveless1 小时前
Oracle打开数据库加密
数据库·oracle
counting money1 小时前
Tomcat 专题:从基础架构到性能调优与 WebSocket 实战
java·websocket·tomcat
m0_462605222 小时前
大模型week02
数据库
DBA_G2 小时前
GBase 8a数据库集群多维度资源管控策略矩阵解析
数据库·oracle
xiaohaiAIgeo2 小时前
【2026年】HG/T 20656-2024化工暖通空调设计规范:新版标准的变化与影响
java·前端·javascript·科普知识