当前位置: 首页 > 面试题库 >

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

江天宇
2023-03-14
问题内容

我想从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实体

问题答案:

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



 类似资料:
  • 问题内容: 嘿,我是新来的hibernate。我不得不说,它确实简化了SQL查询的所有操作。但是,操作返回的结果目前对我来说很头疼。 结果以列表形式返回。大多数时候,我真的希望结果位于结果集中,这样我可以像使用结果集那样更轻松地操作它,可以按列名或索引指定值。在List中,我几乎归自己的贵族所有。 在某种程度上,我可以将列表检索到JSF数据表中,然后直接调用该成员。我不能总是这样做。不要问我为什么

  • 问题内容: 我刚开始学习Go,并通读现有代码以学习“其他人的做法”。在这种情况下,遍历使用go“工作区”,尤其是与项目依赖关系有关的地方。 在处理各种Go项目时,使用一个或多个Go工作区(即$ GOPATH的定义)的常见(或存在)最佳实践是什么?我应该期望有一个类似于我所有项目的中央代码存储库的Go工作区,还是在我处理这些项目时都明确将其分解并设置$ GOPATH(有点像python) virtu

  • 我有一个在几乎所有表中使用GUID作为主键的应用程序,并且我读到使用GUID作为主键时存在性能问题。老实说,我没有看到任何问题,但我即将启动一个新的应用程序,我仍然希望使用GUID作为主键,但我想使用一个复合主键(GUID和另一个字段) 我之所以使用GUID,是因为当您有不同的环境(如“Production”、“Test”和“Dev”数据库)时,以及在数据库之间迁移数据时,它们很好并且易于管理。

  • 直接从HDFS读取文件,而不将其复制到本地文件系统。不过,我将结果复制到本地文件系统。 hduser@ubuntu:/usr/local/hadoop$mkdir/tmp/gutenberg-output bin/hadoop dfs-getmerge/user/hduser/gutenberg-output/tmp/gutenberg-output deprecated:不推荐使用此脚本执行hd

  • 问题内容: 如果您还希望获得结果总数(在进行分页之前),那么在SQL Server 2000、2005、2008、2012中对结果进行分页的最佳方法(从性能角度而言)是什么? 问题答案: 获取结果总数和分页是两个不同的操作。为了这个示例,我们假设您要处理的查询是 在这种情况下,您可以使用以下方法确定结果总数: …这看似效率低下,但假设所有索引等均已正确设置,实际上却表现不错。 接下来,要以分页的方

  • 问题内容: 我正在寻找检查并查看查询是否返回任何结果的最佳方法。我觉得我经常写这部分代码,有时会出错,有时却没有。 例如,我运行此查询以检查是否存在用户名,然后再将新用户名插入数据库。 然后,我想检查一下是否返回了任何结果。这是我这样做的一种方式: 如果第一种方法不起作用,那么有时它将: 然后,我什至看到前几天可以这样做: 做这个的最好方式是什么? 问题答案: 对于PHP 5和7及更高版本,请使用