为什么对 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_keyVARCHAR(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

Source doc

可能改变

注意事项:

  • 我没有办法测试这个。
  • 这不能解决 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