用过数据库或者文件搜索工具的朋友可能都听过“索引”这个词。比如你在公司用 MySQL 存用户数据,为了查得快会加个索引;又或者你在电脑上用 Everything 搜文件,它也是靠索引实现秒出结果。但问题来了:创建索引到底占不占空间?答案是——当然占。
索引不是魔法,它也是数据
很多人以为索引是“加速器”,加了就变快,还不花代价。其实索引本身就是一份额外的数据结构。拿 MySQL 的 B+ 树索引来说,它要把字段值和对应的主键或地址存下来,重新组织成一棵树。这棵树存在硬盘上,自然要占空间。
举个例子,你有一张用户表,100 万条记录,user_name 字段平均长度 10 字节。如果给这个字段加个普通索引,光索引本身可能就要占用几十MB的空间。要是复合索引、覆盖索引加得多,几百MB也不稀奇。
文件搜索工具更明显
像 Everything 这类工具,第一次运行时会扫描整个磁盘,把所有文件名、路径、大小、时间都读一遍,然后建个索引库存在本地。你在设置里能找到它的索引文件位置,一看就知道不小。尤其是你有几TB的资料盘,索引文件轻松上百MB。
但它换来的是什么?搜“年终总结.docx”,不用几秒就能列出来,而不是让你等几分钟遍历全盘。
权衡的是速度和空间
所以关键不是“要不要索引”,而是“值不值得”。如果你的表很少查,或者数据量小,加索引反而浪费空间。但要是经常按某个字段查,比如订单表按手机号查记录,那建个索引带来的查询提速,远比多占一点磁盘划算。
另外,现代数据库都支持在线建索引,MySQL 8.0 以后还能不锁表。你可以在业务低峰期悄悄加上,用户几乎感觉不到。
怎么查看索引占了多少空间?
在 MySQL 中,可以通过 information_schema 统计索引大小:
SELECT
table_name AS `表名`,
index_name AS `索引名`,
ROUND(stat_value * @@innodb_page_size / 1024 / 1024, 2) AS `大小(MB)`
FROM mysql.innodb_index_stats
WHERE table_name = 'your_table_name'
AND database_name = 'your_db_name'
AND index_name != 'PRIMARY';
执行这条语句,就能看到每个索引实际占了多少空间。心里就有数了。
小建议:别乱加,也别怕加
有人因为怕占空间,一个索引都不敢建,结果查询慢得要命;也有人图省事,每个字段都加索引,写入变慢还浪费资源。合理的做法是:根据查询频率和字段选择性来判断。
比如性别字段只有男女两种值,加索引效果很差,反而拖累插入速度。而订单号、身份证这种唯一性强的字段,就是索引的好对象。
说到底,索引就像家里的收纳盒。多买几个确实占地方,但找东西快啊。只要别堆满客厅就行。