当前位置: 首页 > news >正文

在 MySQL 中建索引时需要注意哪些事项?

在 MySQL 中建立索引是优化查询性能的关键操作,但若使用不当可能导致存储开销增加、写入效率降低甚至性能反降。以下是建索引时需要重点注意的事项及对应分析:


一、索引设计原则

  1. 选择高选择性列

    • 原理:选择性 = 不同值数量 / 总行数,值越接近1(如主键、唯一ID)越适合建索引。
    • 反例:对性别(男/女)建索引,选择性仅0.5,优化效果极低,不如全表扫描。
    • 建议:优先为WHERE、JOIN、ORDER BY中频繁出现的列建索引。
  2. 避免过度索引

    • 代价:每个索引需占用存储空间(B+树结构),且写入(INSERT/UPDATE/DELETE)时需额外维护索引。
    • 案例:一张10万行、10个索引的表,写入速度可能比无索引表慢3倍以上。
    • 工具:通过SHOW INDEX FROM 表名监控索引使用频率,删除长期未使用的索引。
  3. 复合索引的列顺序

    • 原则:遵循“最左前缀”规则,将选择性高、过滤性强的列放在左侧。
    • 示例:索引(a, b, c)可优化a=1a=1 AND b=2a=1 AND b=2 AND c=3,但无法优化b=2c=3单独查询。
    • 反例:将(user_id, create_time)改为(create_time, user_id)后,按时间范围查询的效率可能大幅下降。

二、索引类型选择

  1. 普通索引 vs 唯一索引

    • 普通索引:允许重复值,适用于频繁更新的列。
    • 唯一索引:强制唯一性,适合主键或业务唯一键(如手机号),但写入时需检查重复。
  2. 前缀索引

    • 适用场景:对长字符串(如URL、邮箱)建索引时,可截取前N个字符。
    • 语法ALTER TABLE 表名 ADD INDEX idx_name (column_name(10))
    • 限制:无法用于ORDER BY或GROUP BY,需权衡选择性。
  3. 全文索引(FULLTEXT)

    • 适用场景:对文本内容(如文章、商品描述)进行模糊搜索。
    • 注意:仅支持MyISAM(5.6前)和InnoDB(5.6+),且默认不支持中文分词(需使用ngram插件)。
  4. 空间索引(SPATIAL)

    • 适用场景:地理空间数据(如Point、Polygon)的查询。
    • 限制:仅支持MyISAM(5.7前)和InnoDB(5.7+),且列必须为NOT NULL

三、索引使用优化

  1. 避免索引失效

    • 常见陷阱
      • 对索引列使用函数(如WHERE YEAR(create_time) = 2023)或隐式转换(如字符串与数字比较)。
      • 使用NOT IN!=<>OR(除非所有条件列均有索引)。
      • 查询条件范围过大(如age > 80且数据分布不均)。
    • 解决方案:改用等值查询、拆分ORUNION ALL、调整查询逻辑。
  2. 覆盖索引(Covering Index)

    • 原理:索引包含查询所需的所有列(如SELECT a, b FROM t WHERE a=1,索引(a, b)),避免回表。
    • 优势:减少I/O操作,提升查询速度。
  3. 索引下推(ICP)

    • 适用场景:MySQL 5.6+对复合索引的优化,将WHERE条件过滤下推到存储引擎层。
    • 示例SELECT * FROM t WHERE a=1 AND b>10,索引(a, b)下可先过滤a=1再检查b>10

四、其他注意事项

  1. 外键与索引

    • 建议:对外键列自动建索引(InnoDB默认行为),避免JOIN时全表扫描。
  2. 自增主键 vs 业务主键

    • 自增主键:适合InnoDB(聚簇索引),写入性能高。
    • 业务主键:如UUID,可能导致索引碎片化,需定期OPTIMIZE TABLE
  3. 索引监控与维护

    • 工具
      • EXPLAIN:分析查询是否使用索引。
      • SHOW STATUS LIKE 'Handler_read%':监控索引读取次数。
    • 定期任务:对大表重建索引(ALTER TABLE ... ENGINE=InnoDB)。

五、总结

场景索引策略避免操作
高选择性列建普通索引或唯一索引对低选择性列建索引(如性别)
复合查询按“最左前缀”设计复合索引随意调整索引列顺序
长字符串查询建前缀索引全字段索引(浪费空间)
模糊搜索建全文索引(需分词)LIKE '%keyword%'(无法用索引)
地理空间数据建空间索引用普通索引查询空间数据

核心原则:索引设计需平衡查询效率与写入开销,通过EXPLAIN和监控工具持续优化。

我正在程序员刷题神器面试鸭上高效准备面试,9000+ 高频面试真题、800 万字优质题解,覆盖主流编程方向,跟我一起刷原题、过面试:点击进入

http://www.xdnf.cn/news/214993.html

相关文章:

  • 使用Spring Boot实现WebSocket广播
  • 二叉树左叶子之和(后序遍历,递归求和)
  • VScode与远端服务器SSH链接
  • NS-SWIFT微调Qwen3
  • Electron Forge【实战】桌面应用 —— 将项目配置保存到本地
  • 【含文档+PPT+源码】基于微信小程序的乡村振兴民宿管理系统
  • BLE技术,如何高效赋能IoT短距无线通信?
  • 【展位预告】正也科技将携营销精细化管理解决方案出席中睿营销论坛
  • 数据库系统概论|第三章:关系数据库标准语言SQL—课程笔记7
  • Unity Audio DSP应用与实现
  • C++多线程与锁机制
  • JavaScript函数声明大比拼
  • yolov8使用
  • 10 基于Gazebo和Rviz实现导航仿真,包括SLAM建图,地图服务,机器人定位,路径规划
  • BIM(建筑信息模型)与GIS(地理信息系统)的融合的技术框架、实现路径与应用场景
  • 【MCP Node.js SDK 全栈进阶指南】高级篇(2):MCP高性能服务优化
  • MCP 协议 ——AI 世界的 “USB-C 接口”:从认知到实践的全面指南
  • 源码角度分析 sync.map
  • Silvaco仿真中victory process的蒙特卡洛(Monte Carlo)离子注入
  • [4-06-09].第10节:自动配置- 分析@SpringBootApplication启动类
  • github使用记录
  • Redis分布式锁使用以及对接支付宝,paypal,strip跨境支付
  • 第十六届蓝桥杯大赛网安组--几道简单题的WP
  • HTTP协议重定向及交互
  • 运放参数汇总
  • mac word接入deepseek
  • LVGL -窗口操作
  • Linux/AndroidOS中进程间的通信线程间的同步 - 管道和FIFO
  • 【C++编程入门】:基本语法
  • Java 多线程基础:Thread 类详解