当前位置: 首页 > news >正文

MySQL查询性能优化核心知识点总结

一、第一步:精准定位“待优化查询”

优化的前提是“找到问题查询”,而非盲目优化。需结合日志与工具,筛选出“影响最大”的查询,优先处理高价值目标。

1. 发现慢查询:日志与工具双管齐下

(1)日志定位:常规查询日志 vs 慢速查询日志

MySQL通过两种日志记录查询行为,核心关注慢速查询日志(聚焦低效查询):

| 日志类型       | 作用     | 配置与使用       |

| 常规查询日志 | 记录所有SQL请求(SELECT/INSERT/UPDATE等),用于审计或全量查询追踪| 配置:`general_log=ON`,日志路径`general_log_file=/var/log/mysql/general.log`;<br>注意:生产环境慎用(日志量大),仅临时排查时开启。 |

| 慢速查询日志 | 记录执行时间超过`long_query_time`(默认1秒)的查询,是优化核心依据         | 配置:`slow_query_log=ON`,`long_query_time=1`(可设为0.1秒捕捉更多慢查询),日志路径`slow_query_log_file=/var/log/mysql/slow.log`;<br>关键参数:`log_queries_not_using_indexes=ON`(记录未用索引的查询)。 |

(2)实时工具:快速捕捉活跃慢查询

- SHOW PROCESSLIST`:查看当前活跃连接的SQL执行状态,识别“长期阻塞”或“耗时查询”:  SHOW PROCESSLIST\G

  - 关键字段:`Time`(执行时间,超过10秒需关注)、`State`(状态,如`Sending data`可能是慢查询)、`Info`(具体SQL)。

- `sys.statement_analysis`:查看“规范化查询”的聚合统计(如执行次数、总耗时),定位高频查询:  SELECT query, exec_count, total_latency FROM sys.statement_analysis ORDER BY total_latency DESC LIMIT 10;

  - 优势:将相似查询(如`WHERE id=1`和`WHERE id=2`)合并,避免重复统计。

2. 选择优化对象:不是“最慢”而是“影响最大”

优化的核心原则:优先优化“执行频繁的查询”,而非仅关注“单次最慢的查询”。 

二、第二步:用EXPLAIN剖析“查询执行计划”

`EXPLAIN`是MySQL查询优化的“显微镜”——它不执行SQL,仅输出优化器的“执行计划”,帮你判断查询是否用对索引、是否有全表扫描等问题。

1. EXPLAIN基本用法

支持`SELECT`/`INSERT`/`UPDATE`/`DELETE`语句,语法简单:

-- 分析SELECT语句:EXPLAIN SELECT * FROM employees WHERE emp_no=10001\G

-- 分析UPDATE语句:EXPLAIN UPDATE salaries SET salary=50000 WHERE emp_no=10001\G

2. EXPLAIN输出字段详解(核心必看)

`EXPLAIN`输出12个关键字段,每个字段都对应优化的突破口,重点关注标红部分:

| 字段名          | 含义与优化价值         |

|`id`| 查询语句的编号,复杂查询(子查询、JOIN)会有多行不同id,标识表的处理顺序。|

| `select_type`   | 查询类型:<br>- `SIMPLE`:无子查询/UNION;<br>- `SUBQUERY`:子查询;<br>- `UNION`:UNION语句;<br>无需优化,仅用于理解查询结构。 |

| `table`         | 该计划对应的表名,JOIN查询会有多行(对应不同表)。                             |

| `type`      | 索引/连接类型,最核心的性能指标,从优到差排序:<br>`const`(主键/唯一键匹配常量)>`eq_ref`(JOIN时主键匹配)>`ref`(非唯一索引匹配)>`range`(索引范围扫描)>`index`(全索引扫描)>`ALL`(全表扫描)。 |

| `possible_keys` | 优化器认为“可能有用”的索引,不代表实际使用。                                   |

| key`   | 优化器“实际使用”的索引,若为`NULL`,表示未用索引(需优化)。                     |

| `key_len`       | 实际使用的索引长度(字节),越长表示使用的索引列越多(如联合索引用了前2列)。     |

| `ref`           | 与索引对比的“参考值”:<br>- `const`:常量(如`WHERE id=1`);<br>- `表名.列名`:JOIN时的关联列。 |

| `rows`  | 优化器预估的“扫描行数”,数值越小越好(全表扫描时等于表总行数)。           |

| `filtered`      | 按WHERE条件筛选后的行百分比(%),越高表示筛选效果越好。            |

| `Extra`    | 额外信息,高频优化点:<br>- `Using filesort`:需优化(用索引避免排序);<br>- `Using temporary`:需优化(用索引避免临时表);<br>- `Using index`:最优(覆盖索引,无需回表);<br>- `Using where`:需结合索引判断是否全表扫描。 |

三、第三步:索引优化——查询性能的“加速器”

索引是解决“慢查询”的核心手段,但需选对类型、正确创建,避免“无效索引”浪费资源。

1. MySQL支持的索引类型

不同场景需用不同索引,避免一概而论:

| 索引类型       | 特点与适用场景                                                                 |

| 非唯一索引 | 默认类型,值可重复;适用于`WHERE`条件查询(如`WHERE dept_no='d001'`)。          |

| 唯一索引   | 值唯一(允许NULL);适用于`WHERE`条件+唯一性约束(如`WHERE email='a@xxx.com'`)。 |

| 主键索引  | 特殊的唯一索引,值非空;每个表仅1个,用于唯一标识行(如`emp_no`)。|

| 全文索引 | 针对字符串的全文搜索(如`MATCH(name) AGAINST('apple')`);不适用于精确匹配。     |

| 空间索引   | 针对空间数据类型(如`GEOMETRY`、`POINT`);适用于地理信息查询  |

2. 索引的核心作用(3大场景)

索引不是“万能的”,但能解决90%的慢查询,核心支持三类操作:

1. 直接值匹配:精确查找(如`WHERE id=1`),通过索引直接定位行;

2. 存在性检查:判断值是否存在(如`WHERE email='a@xxx.com'`),避免全表扫描;

3. 范围扫描:查找区间值(如`WHERE salary BETWEEN 5000 AND 10000`),仅扫描索引区间。

3. 索引的创建与删除

(1)创建索引

- 给现有表加索引(`ALTER TABLE`或`CREATE INDEX`)。

- 创建表时直接加索引。

(2)删除索引

-- 方法1:ALTER TABLE(适用于所有索引,包括主键)

ALTER TABLE employees DROP INDEX idx_emp_firstname;

-- 方法2:DROP INDEX(适用于非主键索引)

DROP INDEX idx_title_empno ON titles;

-- 删除主键(需先删主键索引,再重建)

ALTER TABLE dept DROP PRIMARY KEY, ADD PRIMARY KEY (dept_no);

(3)查看索引信息

用`SHOW INDEXES`查看表的所有索引:SHOW INDEXES FROM departments\G

关键字段:`Key_name`(索引名)、`Column_name`(索引列)、`Non_unique`(是否非唯一,0=唯一,1=非唯一)、`Cardinality`(索引基数,越大索引选择性越好)。

四、第四步:维护索引统计——让优化器“判断更准”

MySQL优化器依赖“索引统计信息”(如索引基数、数据分布)选择最优计划,若统计信息过时,可能导致“索引失效”,需定期维护。

1. 索引统计信息的自动更新

InnoDB默认自动维护统计信息,无需手动干预:

- 触发条件:表中10%的行被修改后(如INSERT/UPDATE/DELETE);

- 持久化存储:统计信息存在`mysql.innodb_index_stats`表,重启后不丢失;

- 采样策略:默认采样20个数据页,可通过`innodb_stats_persistent_sample_pages`调整(越大越精准,但耗时更长)。

2. 手动更新统计信息(`ANALYZE TABLE`)

当自动更新不及时(如批量导入数据后),需手动执行`ANALYZE TABLE`:

-- 分析单个表:ANALYZE TABLE salaries;

-- 分析多个表,不写入二进制日志(避免同步到从库):ANALYZE LOCAL TABLE employees, titles;

- 作用:重新计算索引基数、数据分布,让优化器选择正确索引;

- 适用场景:批量插入10万行后、表结构变更后。

3. 索引维护进阶操作

(1)重建索引(优化碎片化)

索引长期使用后会产生碎片(如频繁删除导致空页),需重建优化:

-- 方法1:ALTER TABLE FORCE(重建全表索引,适用于InnoDB)

ALTER TABLE employees FORCE;

-- 方法2:OPTIMIZE TABLE(仅重建全文索引,需先设置参数)

SET innodb_optimize_fulltext_only = 1;

OPTIMIZE TABLE titles;

(2)用mysqlcheck工具批量维护

`mysqlcheck`是命令行工具,支持批量分析/优化表,比SQL更便捷:

# 分析employees库的salaries表

mysqlcheck -u root -p --analyze employees salaries

# 优化所有库的所有表(谨慎使用)

mysqlcheck --login-path=admin --optimize --all-databases

- 核心选项:`--analyze`(执行ANALYZE TABLE)、`--optimize`(执行OPTIMIZE TABLE)、`--check`(检查表健康)。

(3)不可见索引(安全测试索引作用)

想测试“删除索引是否影响性能”,但又怕删错?用“不可见索引”隐藏索引(优化器不使用,但DML仍更新):

-- 创建不可见索引:CREATE INDEX idx_emp_lastname ON employees (last_name) INVISIBLE;

-- 切换为可见:ALTER TABLE employees ALTER INDEX idx_emp_lastname VISIBLE;

- 优势:无需删除重建,测试后若发现索引有用,直接设为可见即可。

(4)直方图(优化非索引列的查询)

对于非索引列,优化器无法知道数据分布(如`c_mktsegment`列的取值频率),此时创建“直方图”可提供额外信息:

-- 给customer表的c_mktsegment列创建直方图(1024个桶)

ANALYZE TABLE customer UPDATE HISTOGRAM ON c_mktsegment WITH 1024 BUCKETS;

- 效果:案例中查询耗时从49.98秒降至6.35秒,因优化器更精准预估筛选后的行数。

http://www.dtcms.com/a/418947.html

相关文章:

  • 自然语言处理(03)
  • 哈尔滨速成网站建设公司装修费用会计分录
  • 做网站亏本太原市城乡建设局网站
  • 基于本地运行的OCR在特别场景的应用
  • 网站被host重定向wordpress图像居中
  • 十大AI驱动的网络安全解决方案对比分析
  • 09.【Linux系统编程】“文件“读写操作,Linux下一切皆文件!
  • SkyVLN: 城市环境中无人机的视觉语言导航和 NMPC 控制;香港科技大学
  • 【React 状态管理深度解析:Object.is()、Hook 机制与 Vue 对比实践指南】
  • react-lottie动画组件封装
  • 哈尔滨网站建设吕新松做搜索引擎网站
  • PostgreSQL 流复制参数 - synchronous_commit
  • BPEL:企业流程自动化的幕后指挥家
  • 企业网站开发一薇设计说明英语翻译
  • 搭建 Nexus3 私服并配置第三方 Maven 仓库(阿里云等)和优先级
  • JVM 深入研究 -- 详解class 文件
  • Apache Airflow漏洞致敏感信息泄露:只读用户可获取机密数据
  • 第十六周-基本量子3
  • 手机微网站怎么制作缪斯国际设计董事长
  • 在 Spring Cloud Gateway 中实现跨域(CORS)的两种主要方式
  • SQL Server从入门到项目实践(超值版)读书笔记 27
  • 【Git】项目管理全解
  • rdm响应式网站开发企业年报网上申报流程
  • 昆山开发区网站制作网站建设文档模板
  • PySide6调用OpenAI的Whisper模型进行语音ASR转写
  • 网站怎么被黑磁力蜘蛛
  • nginx反向代理和负载均衡
  • 外贸seo外贸推广外贸网站建设外贸网站建设网站域名信息查询
  • 新广告法 做网站的python和c++学哪个好
  • 数据科学与数据分析:真正的区别是什么?