为什么对wp_postmeta的引用如此之慢?

时间:2017-05-09 00:49:15

标签: mysql wordpress performance indexing

在WordPress中获取属性(使用MySQL)似乎比必要的慢。

(这是一个自我回答的问题,请继续回答。)

1 个答案:

答案 0 :(得分:3)

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列浪费了空间,并且因为它是PRIMARY KEY而减慢了查询速度,从而避开了(post_id, meta_key)的“自然”“复合”PK。
  • 由于“群集”,InnoDB进一步提升了PK的性能。 (我希望你还没有使用MyISAM!)
  • 如果您使用的是MySQL 5.6(或MariaDB 10.0或10.1),请从meta_key更改VARCHAR(255),而不是VARCHAR(191)。 (如果191还不够,我们可以在一个单独的问题中讨论原因和解决方法。)
  • INDEX(meta_key)是可选的,但如果您想“查找具有特定密钥的帖子”,则需要这些内容。
  • 警告:这些更改将加快许多对postmeta的使用,但不是全部。我不认为它会减慢任何用例。 (如果遇到这些问题,请提供此类查询。这可能是一个缓存问题,而不是真正的降级。)

如果您想提交 CREATE TABLE,我可以提供ALTER将其转换为此内容。

如果您需要为一个帖子提供多个具有相同键名的元键,请使用此解决方案。它几乎与上述建议一样好。

    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

Source doc

可能的ALTER

注意事项:

  • 我无法测试这个。
  • 这不解决767错误
  • 这会保留meta_id,因为某些WP用户指出它被其他表引用。
  • 假设您可能有多个行(post_id,meta_key)组合。 (这似乎是糟糕的架构设计?)
  • 所有这一切都会加速典型SELECTs涉及postmeta。
  • 这也可能适用于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