【问题标题】:MySQL entity and entity's aliases: How to remove UNION?MySQL 实体和实体的别名:如何删除 UNION?
【发布时间】:2023-03-11 23:21:01
【问题描述】:

我在数据库中有这些表:

  • 实体(ID、名称、已删除)
  • entities_aliases(entity_id, alias_id)
  • 别名(ID、姓名)

这个查询工作正常,但由于 UNION 速度很慢,请注意 entity.name 如何与 aliases.name 交换并移至最后一列:

SELECT entities.id, entities.name, entities.deleted, NULL AS main_name
FROM entities
UNION
SELECT entities.id, aliases.name, entities.deleted, entities.name AS main_name
FROM entities
JOIN entities_aliases ON entities_aliases.entity_id = entities.id
JOIN aliases ON entities_aliases.alias_id = aliases.id
ORDER BY name

这种交换对我来说非常重要,我无法删除它,但是随着数据库在宽度(更多字段和链接)和深度(更多记录)方面的发展,UNION 会变得越来越慢。如何摆脱 UNION?

添加: 我需要的输出。例如,我们有实体 1-AAA 和他的别名 1-BBB 和 2-CCC。输出应该是:

  • AAA
  • BBB (AAA)
  • CCC (AAA)

【问题讨论】:

  • 如果您确定对于给定的entity_identities.name 始终与 ANY (aliases.name) 不同,请使用 UNION ALL
  • 我想问一下,你期望从这个查询中得到什么输出,让你想到使用联合的想法?不能说什么合适的查询可以替代这个查询,因为我们真的不知道你期望达到什么结果请进一步解释你想要的结果的逻辑
  • 能不能先把表的结构放到这里做测试再给你答案?你也可以去这里创建它sqlfiddle.com/#

标签: mysql sql performance union


【解决方案1】:

我认为您可以使用 LEFT JOINS 和一些 IF 来实现它:

SELECT e.id, IFNULL( a.name, e.name ) AS name, e.deleted, IF( a.name IS NULL, NULL, e.name ) AS main_name
FROM entities AS e
LEFT JOIN entities_aliases AS ea ON e.id = ea.entity_id
LEFT JOIN aliases AS a ON ea.alias_id = a.id;

如果我明白你想要什么,你希望“name”是别名,或者如果没有别名(按此顺序),则为实体名称,如果没有别名,则 main_name 为 null,并且当您确实有别名时的实体名称。 希望对您有所帮助!

【讨论】:

  • 谢谢你,alghimo,但我还需要 e.name 作为单独的结果记录,而 LEFT JOIN 不提供这个。我需要这样:AAA,BBB (AAA),CCC (AAA),其中 AAA - e.name 和 BBB,CCC 是 a.name。
  • 也许我应该将所有实体名称添加为别名,并使用 LEFT JOIN 将其省略,如果 $name == $main_name 未在括号中显示 main_name,则在 MVC 中进行比较。
【解决方案2】:

以下查询仅使用 UNION ALL 而不是 UNION:

SELECT *
FROM ((SELECT entities.id, entities.name, entities.deleted, NULL AS main_name
       FROM entities
      ) union all
      (SELECT entities.id, aliases.name, entities.deleted, entities.name AS main_name
       FROM entities e join
            entities_aliases ea
            ON ea.entity_id = e.id JOIN
            aliases a
            ON ea.alias_id = a.id
     )
    ) e
ORDER BY name

UNION ALL 从查询中删除“不同”进程。

良好的格式*我主观定义为我做事的方式)使我更容易看到查询。另外:

  1. 确保entities.entity_id 是实体的主键。
  2. 确保 alias.id 是 alias 的主键。

您没有进行任何过滤,因此 entity_aliases 上的外键关系是可选的。

【讨论】:

  • 谢谢!但是我需要额外的 SELECT * 来订购吗?没有它似乎完美无缺。
  • 不,严格来说,你可以在没有外部选择的情况下与 order by 进行联合。
猜你喜欢
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
相关资源
最近更新 更多