索引不会自动生效需WHERE匹配最左前缀且无函数/类型转换JOIN驱动表选择、OR/IS NULL处理、数据分布变化均影响索引使用优化需综合评估数据分布、查询频率与写入压力。WHERE 条件没写对索引根本不会用MySQL 和 PostgreSQL 都不会因为表上有索引就自动走索引——前提是 WHERE 子句能匹配索引的最左前缀且没有隐式类型转换或函数包裹。常见错误现象SELECT * FROM orders WHERE DATE(created_at) 2024-01-01哪怕 created_at 有索引也会全表扫描因为 DATE() 函数导致索引失效。改用范围查询created_at 2024-01-01 AND created_at 避免在索引列上做计算、UPPER()、LIKE %abc前导通配符检查执行计划EXPLAIN SELECT ... 看 key 列是否非 NULLrows 是否明显偏大MySQL 里 FORCE INDEX 不是万能解药加 FORCE INDEX 能绕过优化器误判但代价是失去统计信息更新后的自适应能力而且只对单表生效JOIN 场景下容易失效。使用场景确认某列有高选择性索引但优化器因行数估算偏差选了全表扫描或错误索引。语法SELECT * FROM users FORCE INDEX (idx_status_created) WHERE status 1 AND created_at 2024-01-01必须确保 idx_status_created 是复合索引且字段顺序匹配 WHERE 中的过滤顺序如果表数据分布突变比如 status1 的记录从 1% 涨到 90%FORCE INDEX 反而让查询更慢PostgreSQL 不支持类似语法得用 SET enable_seqscan off 临时关闭顺序扫描但生产环境严禁这么做JOIN 多表时驱动表选错等于白优化SQL 改写中常忽略谁当驱动表outer table决定连接路径和索引是否生效。优化器可能选错尤其当小表没走索引、大表被当作驱动表时。 灵办AI 免费一键快速抠图支持下载高清图片