MySQL 慢查询

什么是慢查询

执行时间超过阈值(比如 1 秒)的 SQL,会被记录到慢查询日志里。慢查询是导致接口超时、数据库 CPU 100%、服务卡顿的头号原因。
默认 MySQL 慢查询日志是关闭的,你得先打开。

临时开启

1
2
3
4
5
6
7
8
9
10
11
-- 开启慢查询日志
SET GLOBAL slow_query_log = 1;

-- 设置慢查询阈值:超过 1 秒就算慢查询(根据业务调整)
SET GLOBAL long_query_time = 1;

-- 日志文件路径
SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow.log';

-- 记录没有使用索引的 SQL(可选,非常有用)
SET GLOBAL log_queries_not_using_indexes = 1;

永久开启(修改 my.cnf/my.ini)

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
log_output = FILE

看哪些日志

  1. 慢查询日志 slow.log(最核心)
    记录所有慢 SQL + 执行时间 + 扫描行数 + 锁等待时间 + 客户端信息。
  2. 错误日志 error.log
    排查死锁、连接失败、磁盘满、内存溢出、崩溃。
  3. 通用查询日志 general_log
    记录所有执行过的 SQL(量极大,生产环境一般不开,只临时排查用)。

分析慢 SQL

EXPLAIN

把慢 SQL 拿出来,前面加 EXPLAIN:

1
2
EXPLAIN SELECT * FROM table_name WHERE condition = 'value';
EXPLAIN SELECT * FROM order WHERE user_id = 1001 AND create_time > '2025-01-01';

重点看这 4 列:
type:最好是 ref /range,最差是 ALL(全表扫描),代表找到数据的难易程度,从快到慢:system > const > eq_ref > ref > range > index > ALL

1
2
3
4
5
ALL:全表扫描 → 绝对要优化
index:遍历索引树 → 基本也要优化
range:范围查询(> < between in)→ 一般能接受
ref:普通索引匹配 → 正常不错
const / system:主键 / 唯一索引精准匹配 → 最快

key:是否命中索引(NULL = 没用到索引)
rows:扫描行数(越大越慢)
Extra:
Using filesort(需要优化排序)
Using temporary(用到临时表,性能差)
Using where(正常)

耗时明细

1
2
3
4
5
6
7
8
9
-- 开启 profiling
SET profiling = 1;

-- 执行你的慢 SQL
SELECT * FROM t1;

-- 查看耗时明细
SHOW PROFILES;
SHOW PROFILE FOR QUERY 1;

能看到:
网络等待
锁等待
磁盘 IO
排序耗时

整体流程

开启慢查询日志
用 pt-query-digest 生成报告(或者用原生工具mysqldumpslow)

1
mysqldumpslow -s t -t 10 /var/lib/mysql/localhost-slow.log

找到 Top 10 最慢 SQL
EXPLAIN 看执行计划
优化索引 / 改写 SQL
再次观察慢查询是否消失

RAG解决了大模型的哪些问题

1. 知识过时、信息滞后问题

2. 幻觉

RAG 强制模型基于检索到的真实原文回答,大幅减少虚构内容。

3. 专业领域知识不足

4. 无法使用私有 / 内部数据

5. 训练成本高、更新难

RAG 只需要更新向量库 / 文档库,几分钟就能完成知识更新,成本极低。

6. 可解释性差、无法溯源

纯大模型回答:
不知道答案从哪来
无法验证、无法追责
RAG 可以返回引用来源片段,实现可追溯、可审计,适合合规场景。

SSE

SSE (Server-Sent Events) 是一种基于 HTTP 协议服务器单向推送技术,允许服务器主动、持续地将数据流发送给客户端(浏览器)。它是 HTML5 标准的一部分,核心是通过一个长期保持打开的 HTTP 连接,实现“一问多答”的流式通信。

一、SSE 核心原理

  1. 连接建立:客户端通过浏览器原生 EventSource API 向服务端发起一个标准 HTTP 请求。
  2. 协议标识:服务端响应头必须设置为 Content-Type: text/event-stream,并保持连接不关闭。
  3. 数据推送:服务端按固定格式(data: 内容\n\n)持续发送数据块。
  4. 客户端接收:浏览器自动解析流数据,触发 onmessage 事件供前端处理。
  5. 自动重连:连接意外断开时,浏览器会自动重试,无需前端写复杂逻辑。

二、为什么用 SSE 做流式输出?(尤其 AI 场景)

1. 场景完美匹配:单向流

  • AI 大模型日志推送新闻/行情更新等场景,只需要服务器向客户端说话,客户端不需要在同一条连接里回话。
  • SSE 是单向推送,没有 WebSocket 那种双向通信的“多余功能”,轻量、无浪费

2. 开发 & 运维极简

  • 纯 HTTP:不用像 WebSocket 那样做协议升级(Upgrade)、维护长连接状态、处理复杂心跳。
  • 原生 API:前端一行 new EventSource(url) 搞定,自带断线重连、事件类型、消息ID
  • 易穿透:基于标准 HTTP/HTTPS,防火墙/代理几乎都兼容,部署成本远低于 WebSocket。

3. 流式体验最优(打字机效果)

  • 大模型是逐 Token 生成:生成一个字就推一个字。
  • SSE 天然支持分块传输、边生成边推送,用户不用等完整结果,实时看到输出,体验流畅。
  • 对比:
    • 轮询:有延迟、大量无效请求、浪费带宽。
    • WebSocket:太重、双向、维护复杂,AI 场景属于过度设计

4. 协议简单、易调试

  • 文本格式、人类可读,抓包就能看,排错方便
  • 服务端只要按 data: xxx\n\n 发即可,几乎所有语言/框架都支持

三、SSE vs WebSocket vs 长轮询(关键区别)

特性 SSE WebSocket 长轮询
通信方向 服务器 → 客户端(单向) 双向全双工 客户端主动拉
协议 标准 HTTP/HTTPS 独立 WebSocket 协议 HTTP
开发成本 极低(原生API) 高(连接管理、重连、心跳) 中(需手动重连)
自动重连 ✅ 内置 ❌ 需自己写 ❌ 需自己写
适合场景 AI流式、通知、行情、日志 聊天、游戏、协同编辑 低实时性、简单通知
开销 中(长连接) 高(频繁重连)

四、总结

SSE 就是为“服务器单向持续推流”场景量身定做的技术
在 AI 对话、实时文本流这类需求下:

  • 轮询更实时、更省资源;
  • WebSocket 更简单、更轻量、更易运维。
    所以现在几乎所有 AI 产品(ChatGPT 等)的打字机流式输出,底层都是 SSE。
特性 SSE WebSocket 长轮询
通信方向 服务器 → 客户端(单向) 双向全双工 客户端主动拉
协议 标准 HTTP/HTTPS 独立 WebSocket 协议 HTTP
开发成本 极低(原生 API) 高(连接管理、重连、心跳) 中(需手动重连)
自动重连 ✅ 内置 ❌ 需自己写 ❌ 需自己写
适合场景 AI 流式、通知、行情、日志 聊天、游戏、协同编辑 低实时性、简单通知
开销 中(长连接) 高(频繁重连)