【问题标题】:Why are references to wp_postmeta so slow?为什么对 wp_postmeta 的引用这么慢?
【发布时间】:2017-10-07 03:31:38
【问题描述】:

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

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

【问题讨论】:

    标签: mysql wordpress performance indexing entity-attribute-value


    【解决方案1】:

    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
    

    【讨论】:

    • 很好,但是您能逐步说明如何更改默认值以使用它吗?还记得大多数人使用默认数据库设置来设置 wordpress..那么如何从默认设置获得您的解决方案?
    • 好的,我添加了一条 SQL 语句,还有很多注意事项。
    • 这个解决方案将我的 postmeta 查询时间从 32 秒提高到了 4.9 秒。
    • 我已经在我的测试环境中使用您的 ALTER 查询实现了这一点,它极大地提高了 wp_postmeta 的性能。在我看来,这个问题(和解决方案)似乎很少受到关注。这是为什么?有什么缺点吗?我有点担心在具有 2M+ postmeta 行的生产环境中更改该表。顺便说一句:我到处都听到 wp_postmeta 表是如何被严重优化的。 2020年怎么还是这样?
    • @RickJames 和我有一个新的 WordPress 插件,GPL 和免费的,来处理 postmeta 和类似表的重新键入。 wordpress.org/plugins/index-wp-mysql-for-speed
    猜你喜欢
    • 1970-01-01
    • 2021-09-03
    • 2016-08-09
    • 2020-05-03
    • 2016-09-28
    • 2020-02-08
    • 2012-07-17
    • 2011-11-07
    • 2015-08-24
    相关资源
    最近更新 更多