mysql如何使用忽略索引_mysql ignore index语法

6次阅读

mysql如何使用忽略索引_mysql ignore index语法

mysql 什么时候必须用 IGNORE INDEX

不是“想忽略就忽略”,而是当优化器选错索引、导致查询变慢甚至卡死时,才需要人工干预。典型场景是:表有多个复合索引,WHERE 条件覆盖了多个字段,但 MySQL 选了区分度低的前缀字段索引,或者选了包含大量重复值的列作为驱动索引。

常见错误现象:EXPLAIN 显示 key 列非空但 rows 高得离谱(比如几十万),实际结果只返回几条;或 typerange 却比全表扫描还慢。

  • 只在确认 EXPLAIN 结果异常且已排除统计信息过期(ANALYZE table)后使用
  • 不能用于主键或唯一索引被强制跳过后的语义错误场景(比如 WHERE id = ?IGNORE INDEX (PRIMARY),会退化成全表扫,且无法利用主键约束)
  • IGNORE INDEX 是语句级提示,不改变表结构,也不影响其他查询

IGNORE INDEX 的写法和生效范围

语法必须紧贴 FROM 子句,位置错了直接报错或静默失效。它只对当前 select(或 UPDATE/delete)生效,不能跨子查询继承

错误写法示例:SELECT * FROM t1 IGNORE INDEX (idx_a) WHERE a=1 —— 缺少 usingfor JOIN 关键字,MySQL 5.7+ 会报 Error 1064

  • 基本格式:SELECT * FROM t1 IGNORE INDEX (idx_name) WHERE ...
  • 多索引忽略:IGNORE INDEX (idx_a, idx_b),括号内用英文逗号分隔,无空格要求但建议统一
  • 指定索引类型无效:IGNORE INDEX USING HASH (...) 不合法,MySQL 不支持按类型忽略
  • 别名表必须在 FROM 后立即写提示:SELECT * FROM t1 AS a IGNORE INDEX (idx_a) WHERE a.x = 1

为什么 FORCE INDEX 有时比 IGNORE INDEX 更安全

IGNORE INDEX 是“减法思维”——告诉优化器“别用这几个”,但没说“该用哪个”。如果剩下可用索引都不合适,它可能 fallback 到全表扫描,而你完全没感知。

对比来看:FORCE INDEX (idx_c) 是“加法思维”,明确指定路径,只要该索引能覆盖查询条件,就能稳定走索引扫描。

  • 当已有明确更优索引时,优先用 FORCE INDEX,避免“忽略后无路可走”
  • IGNORE INDEX 更适合调试阶段:先禁掉可疑索引,看 EXPLAIN 是否转向预期索引
  • 注意兼容性:FORCE INDEX 在 MySQL 5.0+ 全版本支持;IGNORE INDEX 从 5.1 开始支持,但早期版本行为略有差异(如 5.1.12 前不支持多索引列表)
  • 分区表中,IGNORE INDEX 对全局二级索引有效,但对分区键上的本地索引需额外验证是否真正跳过

容易被忽略的坑:提示不生效的三种情况

写了 IGNORE INDEX 却发现执行计划没变?大概率掉进这三个坑里。

  • 索引名写错或大小写不匹配:MySQL 在默认配置下索引名大小写敏感(尤其在 linux 文件系统上),IGNORE INDEX (IDX_A) 和实际索引名 idx_a 不等价
  • 查询涉及隐式类型转换:比如 WHERE varchar_col = 123,MySQL 会放弃所有索引(包括被 IGNORE 的),此时提示根本没机会起作用
  • 优化器判定“即使忽略也无索引可用”:例如只有一条索引且被 IGNORE,又没覆盖全部 WHERE 字段,它会直接走全表扫描,且 EXPLAINkey 列显示 NULL,看起来像提示失效

真正难处理的是第三种——它意味着你得先确认“有没有其他可用索引”,而不是盯着提示本身调。

text=ZqhQzanResources