摘要:作为数据库核心优化手段,索引设计直接影响查询性能。但在实际场景中,即使创建了索引,仍可能因设计不当导致全表扫描。今天小编通过真实示例解析5种典型索引失效场景,并提供可靠的优化方案。
作为数据库核心优化手段,索引设计直接影响查询性能。但在实际场景中,即使创建了索引,仍可能因设计不当导致全表扫描。今天小编通过真实示例解析5种典型索引失效场景,并提供可靠的优化方案。
当使用联合索引时,查询条件未包含最左列或未按顺序使用索引列时,将无法触发索引。
某电商用户表结构:
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), age INT, city VARCHAR(20), KEY idx_name_age (name,age));执行范围查询:
SELECT * FROM users WHERE age > 25;执行计划显示type=ALL(全表扫描)
对索引列使用函数、算术运算或类型转换时,将导致索引失效。
订单表时间查询:
CREATE TABLE orders ( id INT PRIMARY KEY, amount DECIMAL(10,2), create_time DATETIME, KEY idx_create_time(create_time));-- 错误写法SELECT * FROM orders WHERE DATE_FORMAT(create_time,'%Y-%m-%d') = '2023-08-01';执行计划显示type=ALL
解决方案改用范围查询:SELECT * FROM orders WHERE create_time BETWEEN '2023-08-01 00:00:00' AND '2023-08-01 23:59:59';使用生成列(MySQL 5.7+):ALTER TABLE orders ADD COLUMN create_date DATE AS (DATE(create_time)) STORED,ADD INDEX idx_create_date(create_date);字段类型与查询值类型不一致时,MySQL会进行隐式转换,导致索引失效。
典型案例商品表字符串主键:
CREATE TABLE products ( id VARCHAR(20) PRIMARY KEY, name VARCHAR(100));-- 错误写法(数字类型查询)SELECT * FROM products WHERE id = 10086;执行计划显示type=ALL
保持类型一致性:
SELECT * FROM products WHERE id = '10086';执行查询计划变为type=const
当OR连接的条件中存在未建立索引的列时,整个查询将退化为全表扫描。
典型案例员工信息查询:
CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(50), department VARCHAR(50), KEY idx_name(name));-- 错误写法SELECT * FROM employees WHERE name = '王伟' OR department = '技术部';执行计划显示type=ALL
当索引列区分度低于30%时,优化器可能认为全表扫描效率更高。
典型案例用户性别查询:
CREATE TABLE members ( id INT PRIMARY KEY, gender ENUM('M','F'), KEY idx_gender(gender));-- 低效查询SELECT * FROM members WHERE gender = 'M';执行计划显示type=ALL
前提条件:表中有大量数据,并且性别分布大致均匀(即大约一半是'M',另一半是'F')。
解决方案ALTER TABLE members ADD INDEX idx_gender_city(gender,city);使用覆盖索引:-- 主要关心的是用户的ID和性别 可以创建如下索引CREATE INDEX idx_gender_id ON members(gender, id);SELECT id FROM members WHERE gender = 'M';覆盖索引:指的是一个索引包含了查询所需的所有列,这样数据库就可以直接从索引中获取数据,而无需访问表中的实际数据行,从而提高了查询效率。
场景检查要点优化策略联合索引失效EXPLAIN的key_len字段最左前缀匹配原则表达式计算WHERE条件是否包含函数重构查询条件/使用生成列类型转换字段类型与值类型一致性显式类型转换OR条件失效查看执行计划using union改用UNION/建立全覆盖索引低选择性索引计算区分度(COUNT(DISTINCT)/总行数)组合索引/覆盖索引通过精准的索引设计和规避常见陷阱,可使查询性能提升非常大。建议每次创建索引后,通过EXPLAIN验证是否按预期工作,并持续监控慢查询日志进行优化调整。大家如果还有更多索引失效案例场景欢迎评论区沟通交流!
来源:免费高清壁纸大全