url_rewrite 表从几十万增长到数百万甚至更多,后台保存商品和分类越来越慢,导入、索引或前台路由也开始出现延迟。URL Rewrite 多并不自动等于异常:商品数、分类路径、多商店和历史重定向都会扩大记录量。关键是判断增长速度、记录类型和是否存在重复业务路径。

先按类型、商店和重定向统计

SELECT entity_type, store_id, redirect_type, COUNT(*) AS total
FROM url_rewrite
GROUP BY entity_type, store_id, redirect_type
ORDER BY total DESC;

再按创建来源、目标路径或实体抽样。系统生成的商品/分类 rewrite、CMS rewrite 和自定义 rewrite 的处理方式不同。不要直接按 redirect_type 删除,因为 301 可能承载有效的历史 SEO 权重。

分类路径会让商品 Rewrite 成倍增加

启用“Use Categories Path for Product URLs”后,同一商品可能在多个分类路径下生成 URL;多 Store View 会再乘以商店数量。频繁移动分类或修改 URL Key,如果同时保存旧 URL 重定向,会继续累积历史记录。

先根据真实 SEO 策略决定是否需要分类路径和永久历史重定向。关闭配置只影响后续生成并不一定清理旧数据,任何清理都要先导出样本、确认外部链接与流量。

异常增长常来自重复保存和自定义插件

批量导入器如果每次运行都保存所有商品,即使 URL 未变化,也可能触发 rewrite 生成。Observer 或 plugin 在保存后再次 save 同一实体,会把问题放大。检查日志中同一商品的保存次数,并分析最近一次增长与导入、分类调整或扩展上线的时间关系。

数据库唯一索引会阻止完全相同的 request_path/store_id,但不同历史路径、随机后缀或无效 redirect 仍可不断增加。不要通过移除唯一索引来让任务跑完。

表变大影响的不只是前台路由

保存商品/分类需要查找、删除和插入相关 rewrite;大事务会增加锁与 redo。导入和索引可能因批量生成耗时;前台每次请求也需要按 request_path 与 store_id 匹配。确认这些列的索引存在且未损坏,并用 EXPLAIN 检查真实慢查询。

SHOW INDEX FROM url_rewrite;
EXPLAIN SELECT target_path, redirect_type
FROM url_rewrite
WHERE request_path = 'sample.html' AND store_id = 1;

表空间很大时,删除记录并不会自动把磁盘空间全部归还。OPTIMIZE 或在线表重建可能锁表、需要额外磁盘,必须安排维护窗口并评估数据库版本能力。

清理必须有可回滚规则

可以优先识别已不存在实体的孤立 rewrite、指向无效目标的自定义记录和明确过期的历史链,但应先在副本验证查询。对 301 链,尽量把外部入口直接指向最终规范 URL,避免多跳;对仍有流量的旧路径,保留或建立明确替代。

处理后重新统计记录数量和增长速度,测试商品保存、分类移动、CSV 导入、旧链接 301、规范 URL 200 与多商店路由。真正的优化目标是控制后续增长和保存耗时,而不仅是让表暂时变小。