日志表每天删几十万行,文件却一点没变小,查询还越来越慢。这不是玄学,是InnoDB的机制:删除的数据只是打标记,空间留在文件里复用,但反复增删后数据页变得稀碎,扫描效率下降。碎到一定程度就得整理。
先看碎片率再动手,information_schema里直接查。
<pre style="background-color:#282c34;color:#abb2bf;padding:16px 20px;border-radius:8px;overflow-x:auto;font-family:Consolas,'Courier New',monospace;font-size:14px;line-height:1.7;margin:16px 0;-webkit-overflow-scrolling:touch;"><code style="font-family:inherit;">SELECT table_name,
<span style="color:#61afef">ROUND</span>(data_length/<span style="color:#d19a66">1024</span>/<span style="color:#d19a66">1024</span>, <span style="color:#d19a66">1</span>) AS data_mb,
<span style="color:#61afef">ROUND</span>(index_length/<span style="color:#d19a66">1024</span>/<span style="color:#d19a66">1024</span>, <span style="color:#d19a66">1</span>) AS index_mb,
<span style="color:#61afef">ROUND</span>(data_free/<span style="color:#d19a66">1024</span>/<span style="color:#d19a66">1024</span>, <span style="color:#d19a66">1</span>) AS free_mb
FROM information_schema.tables
WHERE table_schema = <span style="color:#98c379">'your_db'</span>
ORDER BY data_free DESC;</code></pre>
free_mb占比高的表值得整理。OPTIMIZE TABLE会重建表文件、压实数据页、重建索引统计信息,一举三得。
<pre style="background-color:#282c34;color:#abb2bf;padding:16px 20px;border-radius:8px;overflow-x:auto;font-family:Consolas,'Courier New',monospace;font-size:14px;line-height:1.7;margin:16px 0;-webkit-overflow-scrolling:touch;"><code style="font-family:inherit;">OPTIMIZE TABLE log_records;
-- 返回 Table does not support optimize... <span style="color:#c678dd">use</span> <span style="color:#61afef">recreate</span>+<span style="color:#61afef">analyze</span> 属正常提示
-- <span style="color:#61afef">InnoDB</span>下它内部等价于 <span style="color:#61afef">ALTER</span> <span style="color:#61afef">TABLE</span> ... <span style="color:#61afef">FORCE</span> 重建
# 大表整理会锁写,挑业务低峰执行
# 或者用在线<span style="color:#61afef">DDL</span>减少阻塞时间
<span style="color:#61afef">ALTER</span> <span style="color:#61afef">TABLE</span> <span style="color:#61afef">log_records</span> <span style="color:#61afef">ENGINE</span>=<span style="color:#61afef">InnoDB</span>, <span style="color:#61afef">ALGORITHM</span>=<span style="color:#61afef">INPLACE</span>, <span style="color:#61afef">LOCK</span>=<span style="color:#61afef">NONE</span>;</code></pre>
注意成本:重建期间该表写入受限,几GB的表要跑几分钟,务必挑低峰。更聪明的路子是把删改为归档——历史数据定期导出到归档表再truncate,主表永远保持苗条,比定期做碎片整理治标又治本。
验证看两处:data_free归零或大幅下降,information_schema里表文件大小更新;对应查询的EXPLAIN里rows预估变准。碎片整理不是日常操作,一个季度看一次数据就够了,天天optimize纯属自我感动。
申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!



