首页 >> 基础教程
mysql创建索引有哪些注意点?
在 MySQL 中创建索引是优化查询性能的关键手段,但不当使用反而会降低系统效率。以下是创建索引时需要注意的核心要点及实践建议:
一、索引创建前的评估
选择高选择性字段
优先考虑:区分度高(不同值多)的列(如
user_id
、phone
),避免低区分度列(如性别、状态标志)。SELECT COUNT(DISTINCT column)/COUNT(*) FROM table; -- 结果 > 0.2 通常适合建索引
分析查询模式
在频繁用于
WHERE
、JOIN
、ORDER BY
、GROUP BY
的列上创建索引。避免为极少被查询的列建索引。
二、索引创建的核心原则
联合索引的最左前缀原则
索引
(a, b, c)
生效场景:WHERE a=? AND b=? AND c=? -- 完全匹配 WHERE a=? AND b=? -- 使用前两列 WHERE a=? -- 使用最左列 WHERE b=? AND c=? -- 不生效(跳过a) WHERE a=? AND c=? -- 仅a生效(c无法利用)
避免冗余索引
例如已存在
(a, b)
,再创建(a)
是冗余的(最左前缀可覆盖)。控制索引数量
写代价:每次
INSERT/UPDATE/DELETE
需更新所有相关索引,索引过多会显著降低写性能。建议:单表索引不超过 5~8 个。
三、特定场景优化策略
前缀索引节约空间
对长文本(
TEXT
/VARCHAR(255)
)使用前缀索引:CREATE INDEX idx_name ON table(column(10)); -- 取前10字
平衡点:保证前缀长度下的选择性接近完整列(避免重复值过多)。
覆盖索引避免回表
若查询只需索引字段,直接使用索引返回数据(无需查主表):
SELECT name, age FROM users WHERE name='Alice'; -- 覆盖索引生效
排序/分组优化
ORDER BY
或GROUP BY
字段与索引顺序一致可避免filesort
CREATE INDEX idx_age_name ON users(age, name); SELECT * FROM users ORDER BY age, name; -- 直接利用索引排序
四、语法与使用陷阱
表达式/函数导致索引失效
SELECT * FROM users WHERE YEAR(create_time)=2023; -- 索引失效 -- 改为范围查询: SELECT * FROM users WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';
隐式类型转换陷阱
-- phone 是 VARCHAR 但查询用数字: SELECT * FROM users WHERE phone = 13800138000; --触发隐式转换,索引失效 -- 改为字符串匹配: SELECT * FROM users WHERE phone = '13800138000';
OR 条件索引失效
SELECT * FROM users WHERE a=1 OR b=2; -- 单列索引可能失效 -- 解决方案: CREATE INDEX idx_a_b ON users(a, b); -- 联合索引(需结合查询优化) -- 或拆分查询: SELECT * FROM users WHERE a=1 UNION SELECT * FROM users WHERE b=2;
五、索引维护与管理
监控索引使用率
-- 查看未使用的索引(Schema为数据库名) SELECT * FROM sys.schema_unused_indexes WHERE object_schema='your_db';
定期重建碎片化索引
ALTER TABLE table_name ENGINE=InnoDB; -- 重建表(包括索引) ANALYZE TABLE table_name; -- 更新统计信息
命名规范与文档化
使用可读性强的命名(如
idx_user_id
、uk_email
)。记录索引创建原因(如
优化订单时间范围查询
)。
六、应避免创建索引的场景
场景 | 原因 |
---|---|
小表(<1000行) | 全表扫描可能比索引更快 |
写频繁 & 读极少 | 索引维护成本 > 查询收益 |
长文本(不设前缀) | 索引体积过大(除非使用全文索引) |
频繁更新的字段 | 更新后需重排序B+树,代价高 |
注意:
不要迷信规则,也要以实际情况为准
用
EXPLAIN
验证索引是否生效(看key
字段)。测试
INSERT/UPDATE
性能是否可接受。避免“凭感觉创建索引”——用数据驱动决策(慢查询日志 + 性能监控)。
超大表要注意创建索引需要考虑对服务器io消耗,别在业务繁忙时候操作
最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29