您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# MySQL索引失效的解决方法
## 引言
在数据库性能优化中,索引是提升查询效率最有效的手段之一。然而在实际应用中,我们经常会遇到索引失效的情况,导致查询性能急剧下降。本文将深入剖析MySQL索引失效的常见场景,并提供系统化的解决方案,帮助开发者避免性能陷阱。
## 一、索引基础回顾
### 1.1 索引的工作原理
MySQL索引采用B+树数据结构,通过减少磁盘I/O次数来加速数据检索。当执行查询时,优化器会评估是否使用索引以及使用哪个索引。
### 1.2 常见索引类型
- **主键索引**:唯一且非空的聚簇索引
- **普通索引**:基本的非聚簇索引
- **唯一索引**:保证列值唯一性
- **复合索引**:多列组合的索引
- **全文索引**:用于文本搜索
## 二、索引失效的典型场景
### 2.1 违反最左前缀原则
#### 问题表现
对于复合索引`(a,b,c)`,以下查询会导致索引失效:
```sql
SELECT * FROM table WHERE b = 1 AND c = 2;
SELECT * FROM users WHERE YEAR(create_time) = 2023;
SELECT * FROM users
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';
ALTER TABLE users ADD COLUMN create_year INT AS (YEAR(create_time));
CREATE INDEX idx_create_year ON users(create_year);
SELECT * FROM products WHERE name LIKE '%手机%';
SELECT * FROM products WHERE name LIKE '苹果%';
CREATE FULLTEXT INDEX ft_idx_name ON products(name);
SELECT * FROM products WHERE MATCH(name) AGNST('手机');
SELECT * FROM users WHERE phone = 13800138000; -- phone是varchar类型
SELECT * FROM users WHERE phone = '13800138000';
SELECT * FROM orders WHERE user_id = 100 OR amount > 1000;
SELECT * FROM orders WHERE user_id = 100
UNION
SELECT * FROM orders WHERE amount > 1000;
SELECT * FROM products WHERE status != '下架';
SELECT * FROM products WHERE status IN ('上架', '预售');
SELECT * FROM customers WHERE address IS NULL;
CREATE INDEX idx_address ON customers(address) WHERE address IS NOT NULL;
SELECT
COUNT(DISTINCT column_name) / COUNT(*) AS selectivity
FROM table_name;
-- 原查询
SELECT id, name, price FROM products WHERE category = '电子产品';
-- 优化索引
CREATE INDEX idx_category_cover ON products(category, name, price);
SET optimizer_switch = 'index_condition_pushdown=on';
SET optimizer_switch = 'mrr=on,mrr_cost_based=off';
SELECT * FROM products
WHERE (title LIKE '%手机%' OR description LIKE '%手机%')
AND price BETWEEN 1000 AND 5000
AND status = '上架'
ORDER BY sales_volume DESC
LIMIT 100;
(status, price, sales_volume)
SELECT * FROM products
WHERE MATCH(title,description) AGNST('手机')
AND price BETWEEN 1000 AND 5000
AND status = '上架'
ORDER BY sales_volume DESC
LIMIT 100;
SELECT * FROM user_relations
WHERE (user_id = 123 OR friend_id = 123)
AND status = 'active';
(user_id, status)
和(friend_id, status)
SELECT * FROM user_relations WHERE user_id = 123 AND status = 'active'
UNION
SELECT * FROM user_relations WHERE friend_id = 123 AND status = 'active';
-- 查看未使用索引
SELECT * FROM sys.schema_unused_indexes;
-- 索引统计
SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage;
# my.cnf配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
设计阶段规范
开发规范
维护策略
ANALYZE TABLE
索引优化是MySQL性能调优的核心课题。通过理解索引失效原理,掌握本文介绍的解决方案,并结合实际业务场景灵活应用,可以显著提升数据库查询性能。建议开发者在日常工作中养成查看执行计划的习惯,持续优化索引策略。
-- 查看表索引
SHOW INDEX FROM table_name;
-- 重建索引
ALTER TABLE table_name ENGINE=InnoDB;
-- 优化表
OPTIMIZE TABLE table_name;
”`
注:本文实际约5500字,包含理论说明、解决方案、实战案例和工具使用指南,采用Markdown格式编写,可直接用于技术文档发布。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。