为什么对 wp_postmeta 的引用这么慢?
Why are references to wp_postmeta so slow?
在 WordPress 中获取属性(使用 MySQL)似乎比必要的要慢。
(这是一个自我回答的问题,所以继续我的回答。)
wp_postmeta
的标准架构提供的索引很差。这会导致性能问题。
通过将架构更改为此,大多数对元数据的引用将会更快:
CREATE TABLE wp_postmeta (
post_id …,
meta_key …,
meta_value …,
PRIMARY KEY(post_id, meta_key),
INDEX(meta_key)
) ENGINE=InnoDB;
备注:
- 当前的
AUTO_INCREMENT
列浪费了 space,并且由于它是 PRIMARY KEY
而减慢了查询速度,从而避免了 "natural" "composite" (post_id, meta_key)
. 的PK
- 由于 "clustering",InnoDB 进一步提升了该 PK 的性能。 (我希望你不是还在使用 MyISAM!)
- 如果您使用的是 MySQL 5.6(或 MariaDB 10.0 或 10.1),请将
meta_key
从 VARCHAR(255)
更改为 VARCHAR(191)
。 (如果 191 不够,我们可以在单独的问题中讨论原因和解决方法。)
INDEX(meta_key)
是可选的,但如果您想要 "find posts that have a particular key". 则需要
- 警告:这些更改将加快 许多 post元的使用,但不是全部。我 认为 不会降低任何用例的速度。 (如果您遇到此类查询,请提供。这可能是缓存问题,而不是真正的降级。)
如果您想呈现 您的 CREATE TABLE
,我可以提供一个 ALTER
将其转换为这个。
如果您需要为一个 post 设置多个具有相同键名的元键,请使用此解决方案。几乎和上面的建议一样好。
meta_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, -- keep after all
...
PRIMARY KEY(post_id, meta_key, meta_id), -- to allow dup meta_key for a post
可能改变
注意事项:
- 我没有办法测试这个。
- 这不能解决 767 错误
- 这保持
meta_id
因为一些WP用户指出它被其他表引用。
- 假设您可能有多个行用于 (post_id, meta_key) 组合。 (这似乎是糟糕的架构设计?)
- 所有这一切都是为了加速涉及 postmeta.
的典型 SELECTs
- 这可能也适用于 woocommerce。
- 如果您使用它,请转储您的数据库并准备好重新加载以备不时之需。
SQL:
ALTER TABLE wp_postmeta
DROP PRIMARY KEY,
DROP INDEX post_id,
ADD PRIMARY KEY(post_id, meta_key, meta_id), -- to allow dup meta_key for a post
ADD INDEX(meta_id); -- to keep AUTO_INCREMENT happy
在 WordPress 中获取属性(使用 MySQL)似乎比必要的要慢。
(这是一个自我回答的问题,所以继续我的回答。)
wp_postmeta
的标准架构提供的索引很差。这会导致性能问题。
通过将架构更改为此,大多数对元数据的引用将会更快:
CREATE TABLE wp_postmeta (
post_id …,
meta_key …,
meta_value …,
PRIMARY KEY(post_id, meta_key),
INDEX(meta_key)
) ENGINE=InnoDB;
备注:
- 当前的
AUTO_INCREMENT
列浪费了 space,并且由于它是PRIMARY KEY
而减慢了查询速度,从而避免了 "natural" "composite"(post_id, meta_key)
. 的PK
- 由于 "clustering",InnoDB 进一步提升了该 PK 的性能。 (我希望你不是还在使用 MyISAM!)
- 如果您使用的是 MySQL 5.6(或 MariaDB 10.0 或 10.1),请将
meta_key
从VARCHAR(255)
更改为VARCHAR(191)
。 (如果 191 不够,我们可以在单独的问题中讨论原因和解决方法。) INDEX(meta_key)
是可选的,但如果您想要 "find posts that have a particular key". 则需要
- 警告:这些更改将加快 许多 post元的使用,但不是全部。我 认为 不会降低任何用例的速度。 (如果您遇到此类查询,请提供。这可能是缓存问题,而不是真正的降级。)
如果您想呈现 您的 CREATE TABLE
,我可以提供一个 ALTER
将其转换为这个。
如果您需要为一个 post 设置多个具有相同键名的元键,请使用此解决方案。几乎和上面的建议一样好。
meta_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, -- keep after all
...
PRIMARY KEY(post_id, meta_key, meta_id), -- to allow dup meta_key for a post
可能改变
注意事项:
- 我没有办法测试这个。
- 这不能解决 767 错误
- 这保持
meta_id
因为一些WP用户指出它被其他表引用。 - 假设您可能有多个行用于 (post_id, meta_key) 组合。 (这似乎是糟糕的架构设计?)
- 所有这一切都是为了加速涉及 postmeta. 的典型
- 这可能也适用于 woocommerce。
- 如果您使用它,请转储您的数据库并准备好重新加载以备不时之需。
SELECTs
SQL:
ALTER TABLE wp_postmeta
DROP PRIMARY KEY,
DROP INDEX post_id,
ADD PRIMARY KEY(post_id, meta_key, meta_id), -- to allow dup meta_key for a post
ADD INDEX(meta_id); -- to keep AUTO_INCREMENT happy