在开发一个电商网站时,用户搜索商品是最常见的操作。比如输入“手机”查找相关产品,系统需要从几万条数据里快速找出匹配项。这时候,数据库里的“索引”就派上用场了。
什么是索引?
可以把它想象成一本书的目录。如果没有目录,想找某一章节就得一页一页翻;有了目录,直接看页码就能定位。数据库索引的作用也一样,它让查询不再全表扫描,而是通过特定结构(比如B+树)快速定位数据。
索引的优点
最明显的好处就是查得快。比如给商品表的 product_name 字段加了索引,再执行下面这条语句时速度会提升很多:
SELECT * FROM products WHERE product_name = 'iPhone 15';
原本可能要扫描上万行数据,现在通过索引几毫秒就返回结果。这对用户体验来说非常重要,尤其是在高并发场景下,响应时间直接影响留存率。
另外,唯一索引还能防止重复数据插入。比如用户注册时用手机号作为唯一索引,系统能自动拦截重复号码的注册请求,避免脏数据进入库中。
索引的缺点
但索引不是免费的午餐。每建一个索引,数据库就要额外维护一份数据结构。就像书本的目录页多了,不仅占空间,每次修改内容还得同步更新目录。
插入、更新、删除数据时,如果有多个索引,这些操作都会变慢。比如你往订单表插入一条记录,不仅要写数据行,还要把各个索引树都更新一遍。索引越多,开销越大。
而且索引会占用磁盘空间。一张千万级的用户表,如果对几个字段都建了索引,可能数据本身占10GB,索引却占了6GB以上。对于云数据库来说,这直接意味着更高的存储成本。
有时候索引还未必生效
比如查询时用了函数处理字段:
SELECT * FROM users WHERE YEAR(reg_time) = 2023;
即使 reg_time 上有索引,这种写法也可能导致索引失效。又或者用模糊查询时把通配符放在开头:LIKE '%北京',这种情况也无法利用索引加速。
更麻烦的是,过多索引会让优化器选择困难。面对十几个索引,数据库不一定选最优的那个,反而可能导致执行计划走偏。
合理使用是关键
一般建议只在经常用于查询条件、排序或连接的字段上建索引。比如 user_id、status、created_at 这类高频筛选字段。
同时定期检查哪些索引长期没被使用,及时清理。MySQL可以通过 information_schema.STATISTICS 或性能模式来分析索引使用情况。
实际项目中见过有人给每个字段都加索引,结果写入性能暴跌,还拖垮了备份速度。最后只能一个个删回去,重新评估哪些才是真正需要的。
索引就像一把双刃剑,用好了事半功倍,用不好反而添乱。理解它的优缺点,才能在真实业务中拿捏好分寸。