今日目标:掌握 Linux 文本处理最强工具(grep/awk/sed),并学会使用 EXPLAIN 分析 SQL 性能瓶颈。今天不只是写代码,而是要彻底理解 “如何高效地处理文本数据”、“索引为什么能提高查询速度” 以及 “如何通过 EXPLAIN 优化 SQL 性能”。
学习内容 (30 mins)
在开始写代码前,先搞懂这些核心概念,否则后面的代码你会看得云里雾里。Shell 三剑客 (15 mins)
Shell 三剑客 (15 mins)
什么是三剑客?grep、awk、sed 是 Linux 文本处理的三大神器,被称为”三剑客”。它们各有所长,组合使用可以处理各种文本处理任务。为什么需要三剑客?
- 日志分析:从大量日志中提取关键信息
- 数据提取:从结构化文本中提取特定字段
- 文本替换:批量修改配置文件
- 数据转换:将数据从一种格式转换为另一种格式
- 作用:在文件中搜索匹配的行
- 基本语法:
grep "pattern" file - 常用选项:
-i:忽略大小写-v:反向匹配(显示不匹配的行)-n:显示行号-c:统计匹配的行数-r:递归搜索目录-E:使用扩展正则表达式
- 实际应用:
- 作用:处理文本文件,按列处理数据
- 基本语法:
awk 'pattern {action}' file - 工作原理:
- 按行读取文件
- 每行按空格或制表符分割成字段
$1、$2、$3分别表示第 1、2、3 列$0表示整行NF表示字段数NR表示当前行号
- 实际应用:
- 作用:流编辑器,用于文本替换、删除、插入
- 基本语法:
sed 's/old/new/g' file - 常用命令:
s:替换(substitute)d:删除(delete)p:打印(print)g:全局替换(global)
- 实际应用:
- 管道组合:将三个工具通过管道连接
- 先用 grep 过滤包含 ERROR 的行
- 再用 awk 提取第二列
- 最后用 sed 删除冒号
SQL 性能优化 (15 mins)
SQL 性能优化 (15 mins)
什么是索引?索引是数据库的”目录”,类似于书籍的目录。它可以帮助数据库快速定位数据,而不需要扫描整个表。为什么需要索引?
- 提高查询速度:从全表扫描变为索引查找
- 加速排序:ORDER BY 操作更快
- 加速连接:JOIN 操作更快
- 唯一性约束:唯一索引保证数据唯一性
- B+ 树结构:索引通常使用 B+ 树存储
- 快速定位:通过索引快速找到数据位置
- 避免全表扫描:不需要扫描所有数据
- 普通索引:最基本的索引,没有任何限制
- 唯一索引:索引列的值必须唯一
- 主键索引:特殊的唯一索引,不能为 NULL
- 复合索引:多个字段组成的索引
- 作用:分析 SQL 语句的执行计划
- 使用方法:
EXPLAIN SELECT ... - 关键字段:
- type:连接类型(性能从好到坏)
system:系统表,只有一行const:主键或唯一索引查询,只有一行eq_ref:唯一索引扫描ref:非唯一索引扫描range:范围扫描index:全索引扫描ALL:全表扫描(最慢,需要优化)
- key:使用的索引
- rows:扫描的行数(越少越好)
- Extra:额外信息
- type:连接类型(性能从好到坏)
- LIKE 左模糊:
LIKE '%keyword'会导致索引失效 - 函数操作:
WHERE YEAR(created_at) = 2024会导致索引失效 - 类型转换:
WHERE id = '123'(id 是 INT)会导致类型转换 - OR 条件:某些情况下 OR 会导致索引失效
- NOT 条件:
WHERE status != 1可能导致索引失效
代码任务 (90 mins)
日志分析脚本
编写 常见错误:验证步骤:
04_log_analysis.sh,分析 Nginx/System 日志:任务分解:- 模拟生成包含 ERROR 和 INFO 的日志文件
- 使用 grep 提取所有 ERROR 行
- 使用 awk 统计 ERROR 出现的次数
- 使用 sed 格式化输出
-
运行脚本:
-
检查输出:
- 应该看到日志文件创建信息
- 应该看到所有 ERROR 行(带行号)
- 应该看到错误信息统计
- 应该看到格式化后的错误消息
-
检查生成的日志文件:
-
测试不同的 grep 选项:
SQL 索引实战
编写 字段类型选择详解:
验证步骤:
04_index_opt.sql:任务分解:- 为用户名添加索引
- 使用 EXPLAIN 分析查询
- 对比有索引和无索引的查询性能
- 演示索引失效的情况
EXPLAIN 结果解读
EXPLAIN 结果解读
type 字段(连接类型):
system:系统表,只有一行(最快)const:主键或唯一索引查询,只有一行eq_ref:唯一索引扫描ref:非唯一索引扫描(常用,性能好)range:范围扫描(如 BETWEEN、IN、LIKE ‘prefix%’)index:全索引扫描(比全表扫描好,但仍需优化)ALL:全表扫描(最慢,需要优化)
- 显示使用的索引名称
NULL表示没有使用索引
- 扫描的行数
- 越少越好
Using index:使用覆盖索引(很好)Using where:使用 WHERE 过滤Using filesort:需要额外排序(可能需要优化)
索引失效的原因
索引失效的原因
1. LIKE 左模糊匹配:2. 函数操作:3. 类型转换:4. OR 条件:
最左前缀原则
最左前缀原则
什么是最左前缀原则?复合索引按照字段顺序从左到右匹配。只有使用索引最左边的字段,索引才会生效。示例:实际应用:
- 创建复合索引时,将最常用的字段放在最左边
- 查询时尽量使用索引最左边的字段
-
连接 MySQL:
-
执行 SQL 脚本:
或者直接复制粘贴 SQL 语句执行
-
查看索引:
-
分析查询:
-
对比性能:
拓展任务 (30 mins)
Shell 挑战
任务:尝试用管道串联三剑客,编写一个脚本从日志文件中提取 IP 地址并统计访问次数。提示:
- 使用
grep过滤包含 IP 的行 - 使用
awk提取 IP 地址(通常是第一列) - 使用
sort | uniq -c统计每个 IP 的访问次数 - 思考:如何用 sed 格式化输出?
SQL 挑战
任务:了解”最左前缀原则”,创建复合索引并测试不同的查询场景。提示:
- 创建
(status, created_at)复合索引 - 测试
WHERE status = 1(应该使用索引) - 测试
WHERE created_at > '2024-01-01'(索引失效) - 思考:如何设计复合索引的顺序?
今日产出物
day04/04_log_analysis.sh- Shell 日志分析脚本day04/04_index_opt.sql- SQL 索引优化脚本
参考代码
查看参考代码
在 GitHub 查看完整的示例代码
在线运行
使用在线编辑器测试代码
实际应用场景
Shell 三剑客在运维中的应用
- 日志分析:使用 grep 过滤错误日志,awk 提取关键信息
- 配置管理:使用 sed 批量修改配置文件
- 数据提取:从命令输出中提取特定字段
- 文本处理:格式化输出,生成报表
- 故障排查:快速定位问题,分析日志
SQL 索引在生产环境的优化
- 查询优化:为常用查询字段添加索引
- 性能监控:使用 EXPLAIN 分析慢查询
- 索引设计:根据查询模式设计合适的索引
- 避免失效:注意索引失效的情况,优化查询语句
- 复合索引:合理使用复合索引提高查询效率
上一天: 管道/函数
Day 03 | Shell 管道与 SQL 联表查询
下一天: 运维实战
Day 05 | Shell 脚本实战与 SQL 优化