【问题标题】:Meta table inefficiencies元表效率低下
【发布时间】:2016-12-04 17:34:36
【问题描述】:

我们的数据库结构以这种方式对我们的大多数核心对象使用元表:

db_object: id (PRIMARY KEY), field1, field2,... db_object_meta:id(主键)、object_id、meta_key、meta_value

我们已经运行了几个月,没有出现任何重大问题,但最近我们遇到了一些严重的延迟,我们的元表可能是罪魁祸首,因为它们已经增长到(500,000 行以上)。

我们主要以直接的方式查询元表,例如:

SELECT `id` FROM `db_object_meta WHERE `object_id` = 9999

SELECT `meta_key`, `meta_value` FROM `db_object_meta WHERE `object_id` = 9999

SELECT `meta_value` FROM `db_object_meta WHERE `object_id` = 9999 AND `meta_key` = 'key1'

似乎是这些类型的查询被阻塞并导致了瓶颈。可以做些什么来提高效率?

向 object_id 列添加 INDEX 是否会提高性能,这是否会使所有现有查询保持不变且无需调整?

我标记了 Wordpress,因为我知道它深入使用了发布元表。

创建表(从评论中添加)

CREATE TABLE wm_object_meta (
    id int(32) NOT NULL, 
    store_id int(32) NOT NULL, 
    object_id int(32) NOT NULL, 
    meta_key varchar(64) NOT NULL, 
    meta_value longtext NOT NULL, 
    PRIMARY KEY (id), 
    KEY object_id (object_id,meta_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

【问题讨论】:

    标签: php mysql wordpress indexing metadata


    【解决方案1】:

    object_id 上的索引可能会有所帮助,这取决于您的表中有多少不同的 object_id 值。一般来说,为 where 子句中使用的任何字段添加索引都有很大的提高性能的机会。

    编辑:不,添加索引不需要您更改任何现有的查询或语句。

    【讨论】:

      【解决方案2】:

      请发帖SHOW CREATE TABLE post_meta;我的回答是基于您提供的模糊信息。

      这三个查询需要 db_object_meta 上的这个索引:

      PRIMARY KEY(object_id, meta_key)
      

      id 没用,应该删除。但这要求太高了,因为它涉及太多地方的太多变化。

      真正的问题是 WP 使用“实体-属性-值”模式设计,这在扩展方面很糟糕。

      【讨论】:

      • 我们喜欢在元行上有 id 以进行精确的删除查询,但事后看来,该列的主键是无用的。这实际上不是一个 WP 数据库,我只是将其包括在内,因为他们几乎所有东西都使用 post_meta,所以我认为这将是元表效率的一个很好的标签。
      • 好的。请提供SHOW CREATE TABLE,可以了解更多详情。 (而且我不会抨击 WP。但我可能仍然会抨击 EAV。)你试过我建议的 PK 了吗?
      • 创建表wm_object_meta (id int(32) NOT NULL, store_id int(32) NOT NULL, object_id int(32) NOT NULL, meta_key varchar(64 ) NOT NULL, meta_value longtext NOT NULL, PRIMARY KEY (id), KEY object_id (object_id,meta_key) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
      • store_id 在哪里适合? (object_id, meta_key) 是“独一无二的”吗?还是您需要 3 列才能获得“唯一”(store_id, object_id, meta_key)