Feign结构与请求链路详解及面试重点解析

🔍 MySQL索引失效的8种常见情况

✅ 1. 对索引字段使用函数或运算

📉 原因索引值被转换,无法命中 B+ 树。

sql 复制代码
-- ❌ 索引失效
WHERE DATE(created_at) = '2024-04-21'
WHERE price + 10 > 100

-- ✅ 改写方式
WHERE created_at BETWEEN '2024-04-21' AND '2024-04-22'
WHERE price > 90

1234567

✅ 2. 索引字段使用不等于(<> / !=

📉 原因:MySQL 优化器通常不会使用索引做不等判断。

sql 复制代码
-- ❌
WHERE age != 18
WHERE name <> '张三'

123

✅ 3. LIKE 模糊匹配左边有通配符

📉 原因:无法使用索引中的前缀匹配。

sql 复制代码
-- ❌ 索引失效
WHERE name LIKE '%三'

-- ✅ 索引有效
WHERE name LIKE '张%'

12345

✅ 4. 联合索引未遵守最左前缀原则

📉 原因:联合索引需要从最左字段开始连续命中。

sql 复制代码
-- 联合索引 (name, age)

-- ✅ 使用 name,命中索引
WHERE name = '张三'

-- ✅ name + age,命中索引
WHERE name = '张三' AND age = 18

-- ❌ age 单独使用,索引失效
WHERE age = 18

12345678910

✅ 5. 使用 OR 连接多个字段时,部分字段无索引

📉 原因:OR 查询必须每个条件都命中索引,才可能用索引。

sql 复制代码
-- ❌ 假如只有 name 有索引,age 没有
WHERE name = '张三' OR age = 18

-- ✅ 拆成 UNION
SELECT * FROM users WHERE name = '张三'
UNION
SELECT * FROM users WHERE age = 18

1234567

✅ 6. 使用 IS NULLIS NOT NULL 不当

  • IS NULL 通常可以使用索引 ✅
  • IS NOT NULL 可能无法用上索引 ❌(取决于 MySQL 版本)
sql 复制代码
-- ✅ 可能使用索引
WHERE deleted_at IS NULL

-- ❌ 通常不使用索引
WHERE deleted_at IS NOT NULL

12345

✅ 7. 数据类型不一致(隐式类型转换)

📉 原因 :类型不一致会导致隐式转换,索引失效。

python 复制代码
-- 假如 id 是 int 类型
-- ❌ 索引失效(字符串类型)
WHERE id = '100'

-- ✅ 索引有效(int 类型)
WHERE id = 100

123456

✅ 8. 强制使用了不合理的索引或全表扫描(比如数据量太小)

📉 原因:优化器判断"索引不如直接扫表快"

  • 小表:几十行的数据,直接全表扫描可能更快
  • 错误的 USE INDEXFORCE INDEX 可能导致反效果

🧠 小技巧:用 EXPLAIN 检查索引是否命中

ini 复制代码
EXPLAIN SELECT * FROM users WHERE name = '张三';

1

看这些字段:

  • type 是否为 ref, range(好)
  • Extra 中有无 Using index, Using where, Using filesort
  • key 是否命中你的索引

✅ 总结一句话:

索引不是万能的,写 SQL 时要避免函数、运算、类型转换、错误顺序、模糊匹配等操作,才能让索引乖乖发挥作用!

🚀 一、SQL 优化的核心目标

简单说就是两个字:快、省

  • :让查询时间尽可能短,毫秒级最好;
  • :资源消耗小(CPU、内存、磁盘 IO),同时避免锁冲突。

🧩 二、我在实际项目中总结的优化步骤(干货)

✅ 1. 优先找出慢 SQL

  • 使用 SHOW PROCESSLIST 发现当前执行慢的 SQL;
  • 使用 slow_query_log 慢查询日志定位;
  • 配合 APM(如阿里云 DBA助手、腾讯 DBbrain)查看执行耗时最多的 SQL。

✅ 2. 使用 EXPLAIN 分析执行计划

  • 看是否走索引?是否出现 type=ALL(全表扫描)?
  • rows 是否过多?
  • 是否出现 Using temporaryUsing filesort(开销大)?

举例分析:

ini 复制代码
EXPLAIN SELECT * FROM users WHERE name = '张三';

1
  • key 显示命中索引:说明有效;
  • type 显示为 refrange:优秀;
  • rows 显示扫描行数:尽可能小;
  • Extra 不要出现 Using temporaryUsing filesort

✅ 3. SQL 结构本身的优化经验

📌 写法层面

  • 避免 SELECT *,明确字段
  • 尽量避免子查询,尤其是 IN (SELECT ...),改成 JOIN 更高效
  • LIMIT + WHERE + ORDER BY 配合用,减少内存压力

📌 语法替换

  • OR 尽量替换为 UNION
  • 大量 IN 优化为临时表 JOIN
  • EXISTS 替换 IN(在子表大、主表小的情况下)

✅ 4. 索引策略优化经验

🔍 索引使用技巧

  • 使用覆盖索引(避免回表)
    👉 SELECT id, name FROM users WHERE name = '张三' (假如 name 有索引)
  • 使用联合索引,遵循最左前缀原则
  • 避免在索引字段上使用函数、运算、!=LIKE '%xx'
  • 注意数据分布情况,低选择度字段(如性别)单独建索引没意义

🧠 动态观察

  • SHOW INDEX FROM table 查看哪些索引被建了,是否被误建或遗漏
  • ANALYZE TABLE + OPTIMIZE TABLE 有助于索引统计信息刷新

✅ 5. 分库分表、缓存、读写分离(进阶)

  • 热点数据缓存(Redis) :频繁查询的数据不查库
  • 读写分离:主库写,从库读,减轻主库压力
  • 水平分表:表数据量超千万时(比如订单表),做分库分表
  • 垂直拆表:一个表字段太多,可以按功能模块拆成多个表

✅ 6. 事务与锁优化

  • 尽量缩小事务范围,降低锁的冲突
  • 用合适的隔离级别(READ COMMITTED 性能更好)
  • 关注是否出现锁等待、死锁(SHOW ENGINE INNODB STATUS

📦 实战例子:一个慢 SQL 的优化过程

原始 SQL:

sql 复制代码
SELECT * FROM orders WHERE DATE(create_time) = '2024-04-21';

1

问题:

  • 使用了函数 DATE(),索引失效;
  • 全表扫描,慢!

优化后:

sql 复制代码
SELECT * FROM orders WHERE create_time BETWEEN '2024-04-21 00:00:00' AND '2024-04-21 23:59:59';

1

效果:

  • 命中 create_time 索引
  • 查询速度提升数十倍

📌 总结:我的 SQL 优化经验口诀

"查慢因、看执行、调结构、用索引、搞缓存、分冷热、控事务"

这几个字基本就是 SQL 优化的大纲思路。不同项目不同瓶颈,优化策略要结合业务和数据特性,逐层深入。

相关推荐
GetcharZp16 分钟前
xterm.js 终端神器到底有多强?用了才知道!
前端·后端·go
洞窝技术39 分钟前
MYSQL:关于索引你想知道的
后端·mysql
MrWho不迷糊1 小时前
企业级权限系统怎么设计四 —— ABAC模型统一功能权限与数据权限
后端·微服务
落尘2981 小时前
Spring MVC——传递参数的方式
后端
ITCharge1 小时前
Docker 万字教程:从入门到掌握
后端·docker·容器
落尘2982 小时前
Bean 的作用域和生命周期
后端
是店小二呀2 小时前
处理Linux下磁盘空间不足问题的实用指南
后端
落尘2982 小时前
如何通过 JWT 来解决登录认证问题
后端
是店小二呀2 小时前
处理Linux下内存泄漏问题的诊断与解决方法
后端
倚栏听风雨2 小时前
IDEA 插件开发 对文件夹下的类进行 语法检查
后端