更新时间:2026-05-06 GMT+08:00
为应用选择和创建最佳索引,加速数据读取
什么是MySQL索引?
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
本文结合实际场景示例介绍如何为数据库表创建最佳索引。
注意事项
- 避免隐式转换:确保索引字段类型与查询条件类型一致,避免因类型不同导致的隐式转换,从而影响索引使用效率。
- 索引长度:对于VARCHAR类型的字段,建立索引时指定合适的索引长度,不必对整个字段建立索引,根据实际文本区分度决定索引长度。
- 避免左模糊查询:尽量避免使用左模糊(如LIKE '%hk')或全模糊查询,这可能导致索引失效,退化为全表扫描。
- 索引数量:单张表的索引数量控制在5个以内,或不超过表字段个数的20%,以避免过多的索引影响写性能。
- 索引使用情况:使用EXPLAIN命令查看SQL执行计划,确保索引被正确使用,避免出现Using File Sort或Using Temporary等影响性能的情况。
- 避免冗余索引:如已存在INDEX(a,b,c),就不需要再创建INDEX(a,b)。
- 索引创建:对于超大表,根据查询需求有针对性地创建索引,避免不必要的索引。可结合onlineDDL工具创建索引。
- 索引删除:删除不必要的索引前,应充分论证,并备份数据,以防误操作。
主要索引类型
- 唯一索引:对于具有唯一特性的字段,建议建立唯一索引。例如,如果表中有字段a和b具有唯一性,可以在这些字段上建立唯一索引。
- 覆盖索引:利用覆盖索引来避免回表操作,提高查询效率。覆盖索引是指查询的所有字段都包含在索引中,可以直接从索引中获取数据。
- 组合索引:创建组合索引时,应将区分度最高的字段放在最左边,以利用B-tree的最左前缀匹配特性。
推荐的索引设计方案
创建一个订单表(cdc-order)。
CREATE TABLE cdc-order ( `order_id` VARCHAR(64) NOT NULL, `order_channel` VARCHAR(32) NOT NULL, `order_time` VARCHAR(32), `pay_amount` DOUBLE, `real_pay` DOUBLE, `pay_time` VARCHAR(32), `user_id` VARCHAR(32), `user_name` VARCHAR(32), `area_id` VARCHAR(32) ) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4;
以订单表(cdc-order)为例,提供以下索引设计方案:
- 主键设计
ALTER TABLE cdc-order ADD COLUMN id INT AUTO_INCREMENT PRIMARY KEY
遵循规范:每个InnoDB表强烈建议有一个主键,最好选择值的顺序是连续增长的列作为主键。
- 联合索引设计
- INDEX idx_user_order (user_id, order_time):用于用户订单查询。
- INDEX idx_channel_time (order_channel, order_time):用于渠道统计。
- INDEX idx_area_time (area_id, order_time):用于地区分析。
- 索引长度优化
INDEX idx_user_name (user_name(20)):字符串索引长度为20即可达到90%以上区分度。