mysql left join子查询 索引失效

改写子查询避免WHERE过滤右表。
用USEINDEX强制索引,但别瞎用。
ANALYZETABLE更新统计信息。
检查类型、运算、函数、模糊查询。
综合调整优化。

mysql降序排序索引失效怎么办

说实话,MySQL里头搞排序这事儿,真是挺磨人的。
我之前有个项目,用户量一上来,查询特别慢,一查执行计划才发现,好家伙,索引直接失效了。
降序排序是罪魁祸首之一,具体怎么解决,我给你掰扯掰扯。

1 . 索引顺序和排序方向那点事儿 我记得特别清楚,有一次查物流订单表,复合索引是 (statusASC, create_timeASC)。
结果用户非要按 status 降序看,ORDER BY status DESC, create_time DESC。
这时候 MySQL 就懵了——status 是降序,索引里却是升序,直接把索引当摆设。

怎么改:要么直接建个新索引 (statusDESC, create_timeDESC),要么干脆拆开,给 status 单独建个降序索引。
但要注意,拆索引后插入数据可能会变慢,得看业务场景。
我之前拆过一次,晚上跑批效率直接掉3 0%。

2 . 最左匹配原则这老规矩 比如有个索引 (user_idASC, order_dateASC),你非得 WHERE order_date='2 02 3 -1 0-2 7 ' ORDER BY user_id DESC,索引就白用了。
因为查询条件没从最左开始,MySQL 直接跳过索引去全表捞数据。

我当时也没想明白,为啥业务要这么查。
后来发现是报表需求,得按日期固定、用户降序。
最后只能加个 (order_dateASC, user_idDESC) 的备用索引。
这种时候,调整索引比改业务逻辑省事。

3 . EXPLAIN 是个宝 以前我写 SQL 总是 SELECT ORDER BY ...,不卡就不查。
后来被带教师傅骂醒,必须用 EXPLAIN。
比如 EXPLAIN SELECT FROM orders ORDER BY create_time DESC;,看 key 列是不是用了索引,Extra 里有没有 Using filesort。
我有个客户表千万条数据,原来全表扫描,改完索引后直接从 5 秒降到0.3 秒。

骚操作:把 EXPLAIN 放进监控脚本,慢查询超过1 秒就发钉钉提醒。
老板还说我是"数据库保镖"。

4 . 函数和表达式是索引的克星 这点特别坑,ORDER BY YEAR(create_time) DESC 直接让 create_time 索引失效。
我有个电商后台,用户非要按 "订单金额的整数部分" 降序看,结果 SQL 变成 ORDER BY FLOOR(amount) DESC,索引全废。

怎么破:要么改查询 ORDER BY create_time DESC,要么在表里加个 year_column 列,批量更新完再建索引。
存储计算结果是个好办法,虽然占点空间,但查询快啊。

5 . 数据类型那点破事儿 有次查用户名,写成 WHERE name='张三',结果字段是 VARCHAR 但没加引号,MySQL 自动当成 name='张三' 去查,索引当然白搭。

我的建议:写 SQL 时字符串条件一定加引号,像 Python 那样。
如果自动加引号不起作用,可以在字段名后加 AS raw_name,然后 WHERE raw_name='张三'。
虽然麻烦,但比索引失效强。

最后说个真实案例,我接手过一个改过三四手的旧系统,执行计划里全是 Using temporary。
一查发现全是 WHERE date_column + INTERVAL 1 DAY = '2 02 3 -1 0-2 7 ' 这种写法,直接把日期索引废了。
改完所有查询后,查询量从8 0%下降到1 0%。
所以说,索引这东西,维护比建索引更考验本事。

mysql索引失效的几种情况

索引失效就废了。
说白了就这几种情况。

用函数就废了。
比如YEAR(date_column)这种。
类型转了也废了。
字符串当数字用就完。
不等于也废了。
age!=2 5 这种。
LIKE带头%就废了。
name LIKE '%Smith'。
OR条件乱来也废。
age=2 5 OR name='John'。
带NULL值也废。
age IS NULL这种。

选择性低的废。
性别这种就别索引了。
复合索引要按顺序。
a,b,c得按顺序用。

优化器说不用就不用。
它觉得全表扫描快。
FORCEINDEX乱用也废。
别瞎加。

怎么避免?好好设计索引。
EXPLAIN看执行计划。
监控数据库统计信息。
覆盖索引能省事。