一尘不染

检索MySQL EAV结果作为关系表的最佳性能是什么

mysql

我想从EAV(实体属性值)表或更具体地从实体元数据表(如wordpress
wp_postswp_postmeta)中提取结果作为“格式正确的关系表”, 以便进行一些排序和/或过滤

我找到了一些有关如何在查询中格式化结果的示例(与编写2个查询并将结果连接到代码中相反),但是我想知道这样做的“最有效”方法,尤其是对于较大的结果套。

当我说“最有效”时,是指类似以下情况:

获取所有具有XYZ之类姓氏的实体

返回按生日排序的实体列表


例如打开这个:

** 实体 **
-----------------------
ID | NAME | 随你
-----------------------
 1 | 鲍勃 等等
 2 | 简| 等等
 3 | 汤姆| 等等

**元**
------------------------------------
ID | EntityID | KEY | 值
------------------------------------
 1 | 1 | 名| 鲍勃
 2 | 1 | 姓| 鲍勃森
 3 | 1 | 生日 1983-10-10
 。| 2 | 名| 简
 。| 2 | 姓| 简斯多特
 。| 2 | 生日 1983-08-10
 。| 3 | 名| 汤姆
 。| 3 | 姓| 汤姆森
 。| 3 | 生日 1980-08-10

到这个:

**结果**
-----------------------------------------------
EID | NAME | 名| 姓| 生日
-----------------------------------------------
 1 | 鲍勃 鲍勃| 鲍勃森| 1983-10-10
 2 | 简| 简| 简斯多特| 1983-08-10
 3 | 汤姆| 汤姆| 汤姆森| 1980-08-10

因此我可以按任何元字段进行排序或过滤。


我在这里找到了一些建议,但找不到任何更好的讨论。

选项

  1. GROUP_CONCAT

    SELECT e。*,GROUP_CONCAT(CONCAT_WS('||',m.KEY,m.VALUE)ORDER BY m.KEY SEPARATOR';;')
    

    ENTITY e JOINMETA m在e.ID = m.EntityID

  2. 多人加入

    SELECT e。*,将m1.VALUE用作“名字”,将m2.VALUE用作“姓氏”,将m3.VALUE用作“生日”
    

    来自“ ENTITY” e
    左联接META m1
    开e.ID = m1.EntityID和m1.meta_key =’名字’
    左联接META m2
    ON e.ID = m2.EntityID AND m2.meta_key =’姓氏’
    左联接META m3
    开e.ID = m3.EntityID和m3.meta_key =’生日’

  3. 合并

    选择e。*
    

    ,MAX(IF(m.KEY =’名字’,m.VALUE,NULL))作为’名字’
    ,MAX(IF(m.KEY =’姓氏’,m.VALUE,NULL))作为’姓氏’
    ,MAX(IF(m.KEY =’birthday’,m.VALUE,NULL))作为’birthday’
    来自“ ENTITY” e
    加入META m
    开启e.ID = m.EntityID

  4. 代码

    从“实体”中选择e。* e其中e.ID = {whatever};
    

在PHP中,根据结果创建一个占位符对象

    从“ META”中选择m。* m,其中m.EntityID = {whatever};

在PHP中,遍历结果并附加到实体对象,例如: $e->{$result->key} = $result->VALUE

一般而言,哪个更适合过滤/排序?

相关问题:

  1. 绑定EAV结果
  2. 如何透视MySQL实体

阅读 249

收藏
2020-05-17

共1个答案

一尘不染

使用数据透视表或聚合的任何内容都可能会更快,因为它们不需要表自连接。基于联接的方法将要求优化器执行多个子查询操作,然后将结果联接在一起。对于较小的数据集,这可能无关紧要,但是如果您要对较大的数据集进行分析查询,则可能会大大降低性能,

2020-05-17