租号玩代理申请
A- A+

WordPress媒体库数据量多了,创建提速查询RAR PDF MP4 文档等数据类型的索引

2026年08月14日 建站相关 暂无评论 阅读 46 次 打印

由于WordPress上传图片和附件时直接保存在post表里的,所以这个表数据越来越多,为了稍微快一点点,对于除了图片以外的其他附件,建议建立联合索引。

图片走原生索引,其他附件走新的联合索引,降低数据库压力。

索引A:

ALTER TABLE wp_posts ADD INDEX `idx_im2828_mime_date` (`post_mime_type`(100), `post_date` DESC, `ID`);

索引B:

ALTER TABLE wp_posts ADD INDEX `idx_im2828_type_mime_date`(`post_type`,`post_status`,`post_mime_type`(100),`post_date` DESC,`ID`);

索引A和索引B只能二选一,建议使用A,更轻量。

两者区别讲解:

## 最左前缀匹配差异

### A:`post_mime_type`放第一位

✅可命中:

- `post_mime_type='xxx'`
- `post_mime_type LIKE 'video/%'`

❌**不能跳过 mime 直接用后面字段**:

>
> 如果 where 不带 post_mime_type 条件,这个索引完全用不上。

### B:`post_type,post_status`放最前面

✅可命中:

1. `post_type + post_status`(不带 mime 条件也能用)
2. `post_type + post_status + post_mime_type`(我们媒体库查询)
3. `post_type + post_status + post_mime_type + order by post_date desc`

B 的适用查询场景更多。

## 2. 针对我们的 SQL:

WHERE post_type='attachment' AND post_status='inherit' AND post_mime_type LIKE 'image/%'
ORDER BY post_date DESC LIMIT 20

- **索引 A**:索引第一列是 mime。MySQL 需要先找出全部 image/% 记录,再做排序。图片数量巨大时,优化器认为开销大,放弃 A,改用`type_status_date`。
- **索引 B**:最左两列直接过滤`post_type='attachment' AND post_status='inherit'`,紧接着过滤 mime,索引内部已经按`post_date DESC`排好序。理论上整条 where+order by 全部可以在索引完成。

>
> 即便 B,当 image 占比极高,MySQL 依然有可能选择原生`type_status_date`,因为原生索引字段更少,体积更小。

## 3. 索引体积 & 写入开销(重点)

- A:3 列 `post_mime_type(100)+post_date+ID`,体积小,写入压力小。
- B:5 列 `post_type+post_status+post_mime_type(100)+post_date+ID`,字段更多,**索引更大,INSERT / UPDATE / DELETE 成本更高**。

wp_posts 每新增 / 修改一行,就要维护这个索引,写多的站点会有可感知损耗。

也就是说:真正高频的编辑器场景不受这个问题影响;只有后台媒体总列表筛选图片才触发这条 SQL。

最后执行查询EXPLAIN 观察:

EXPLAIN SELECT * FROM wp_posts 
WHERE post_type='attachment' AND post_status='inherit' AND post_mime_type LIKE 'image/%' 
ORDER BY post_date DESC LIMIT 20;

理想:`key`使用`idx_im2828_mime_date`,无 filesort。

给我留言

7 * 7 =
评论规范提醒