【问题标题】:How to optimize this complicated EAV MYSQL query?如何优化这个复杂的 EAV MYSQL 查询?
【发布时间】:2012-04-16 09:48:46
【问题描述】:

是否可以优化我写的这个查询

我创建了一种动态虚拟数据库,让我的用户能够在不影响数据库结构的情况下添加自定义字段。这是迄今为止结构的一个非常简化的视图。

tables         | columns

db_cases       | caseid
db_structure   | fieldname
db_data        | fieldname, data, caseid
db_names       | nameid
  • 我们可以通过向 db_structure 添加一行来创建一个新字段
  • 我们希望记录的任何数据都记录到 db_data。
  • 名称存储在 db_names 中,name_id 存储在 db_data 中

我正在尝试将案例输出到 html 表中

希望其余部分是不言自明的,您可以看到它是多么低效。我可以通过连接做同样的事情吗?

SELECT 
case_id,
(SELECT data_field_value 
 FROM db_data 
 WHERE data_case_id = case_id AND data_field_name = 'casestatus'
) AS casestatus,
(SELECT forename_company 
 FROM db_names 
 WHERE name_id = (SELECT data_field_value 
                  FROM db_data 
                  WHERE data_case_id = case_id AND data_field_name = 'client1'
                 )
) AS client1_forename_company
FROM db_cases 

谢谢

【问题讨论】:

  • 我会先将其缩进并使其易于理解。
  • 动态数据库?因此,您将自己的数据库语义放在 SQL 数据库之上?可怕...thedailywtf.com/Articles/The_Inner-Platform_Effect.aspx
  • 从删除它开始。
  • @MarcB 听起来就像 SharePoint(列表)...没什么大不了的 ;-)(实际上,SP 更改了基础表架构并维护内部/漂亮/数据库列名称的映射。)
  • 这是一个非常讨厌的 EAV 风格结构的完美例子。在它把你装箱之前先装箱!

标签: mysql sql database-design optimization entity-attribute-value


【解决方案1】:

其实,Chibuzo 是对的。从删除它开始 :-)) 但在此之前,玩一下它,这是一个很好的大脑锻炼,就像国际象棋之类的 :-)

select 
    case_id,
    d_status.data_field_value as case_status,
    d_client1_name.forename_company as client1_forename_company
from db_cases 
        join db_data as d_status 
            on d_status.data_case_id = case_id 
               AND d_status.data_field_name = 'casestatus'
        join db_data as d_client1
            on d_client1.data_case_id = case_id 
               AND d_client1.data_field_name = 'client1'
        join db_names as d_client1_name
            on d_client1_name.name_id = d_client1.data_field_value

我希望这些没有子查询的直接连接效率更高,尽管您必须对其进行测试 - 优化中经常会出现意外情况。

【讨论】:

  • 感谢 Tomas,这是一种享受,现在正在快速完成查询,但是我不能忽略这个线程上关于 EAV 不是一个好主意的建议。除了维护这样一个数据库(已经完成)所需的代码量之外,我还能问为什么这样的模型会受到高度反对?缩放?
  • @amof,所以你说它实际上比原始查询快得多?多少钱?
  • 最初我无法运行超过 2000 个案例和 1 个字段的查询,它在 30 秒后超时,现在我能够运行超过 2000 个案例和 10 个字段的查询 - 它几乎是即时的。目前我的模型有哪些替代品?
  • @amof - 在单个通用 VARCHAR 中存储不同类型的数据效率低下。 EAV,尤其是像这样实施时,不能很好地扩展。如果该字段将被密集填充,则直接修改基础表更有意义。您仍然需要正确地实现对本机数据字典的某种扩展。根据您的用例,6NF 可能是您的用户定义字段的合适方法。如果您在 SO 中搜索“EAV 6NF 性能”,您将找到类似问题的一些详细答案。最佳方法很大程度上取决于您的要求。
  • 谢谢@amof,我预计会有所不同,但没有那么大!关于设计问题,我可以看到所有的查询和维护都会非常复杂,所以我会尽量避免这种情况并尽可能简化它。我可能会看一些专门为此目的而制定的解决方案,比如 XML 数据库……但我真的不推荐,对这个用例没有任何经验。至少我很高兴听到现在查询速度很快!
猜你喜欢
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
相关资源
最近更新 更多