【问题标题】:Mysql left join taking too long or crashing... please helpMysql离开加入时间太长或崩溃......请帮助
【发布时间】:2011-07-03 21:50:14
【问题描述】:

大家好,我正在工作中创建报告,由于某种原因,在使用左连接时遇到了一些严重的问题。我有两个表,一个 u_entities 表和一个 u_activities 表,其中存在从实体到活动的一对多关系。我需要找出哪些实体没有与之关联的活动。所以我想将连接实体留在活动中并列出空的活动。所以我的查询看起来像这样

              SELECT *
              FROM (SELECT a.activity_id, e.entity_id, e.acc_name
                    FROM u_entity AS e
                    LEFT JOIN u_activity AS a
                    ON e.entity_id = a.account_id) AS i
              WHERE i.activity_id = ''

这需要的时间太长,所以只是为了查看左连接的结果,我尝试在 phpmyadmin 中运行子选择,看起来像这样

                    SELECT a.activity_id, e.entity_id, e.acc_name
                    FROM u_entity AS e
                    LEFT JOIN u_activity AS a
                    ON e.entity_id = a.account_id

我遇到了同样的问题,服务器一直在工作,但它永远不会完成。我不得不使用 xammp 在我的本地计算机上获取表格并运行查询,因为人们需要服务器并且它被锁定了。当我在本地主机端的 phpmyadmin 中运行第二个查询时,我的计算机崩溃了。实体表有大约 20,000 条记录和大约 80000 条记录,但我之前已经对这些表进行了内部连接,没有问题我不明白为什么这是一个问题。也许我的查询是错误的或什么的。我以前从未做过左连接,所以我不知道。如果有另一种方法可以做到这一点,那会很酷,但我真的很想知道为什么左连接不能正常工作。请任何回应将不胜感激。

【问题讨论】:

  • 你能在两个查询(或至少内部查询)上发布解释吗?
  • 至少应该在 e.entity_id、a.account_id、i.activity_id 上有一个索引
  • 我同意@Dagon。这些表是如何编入索引的?

标签: php mysql sql


【解决方案1】:

作为注释,获取没有活动的实体的更快方法是做


SELECT e.id, ...
FROM u_entity e
LEFT JOIN u_activity a ON e.entity_id=a.account_id
WHERE ISNULL(a.account_id)

关于运行缓慢的问题,您要确保已在连接中使用的列(在本例中为entity_idaccount_id)创建索引并且它们是最新的(运行repair table u_entityrepair table u_activity - 如果您的表是 MyISAM)。您真的应该运行EXPLAIN SELECT...(将所有查询放在EXPLAIN 部分之后)并在此处发布结果以获得更好的帮助。

【讨论】:

  • 嘿,您的查询在 1.4171 秒内工作,所以我没有费心解释,但它在 phpmyadmin 中加载需要五分钟。为什么会这样?
  • 因为您的版本首先运行子查询,获取所有实体,加入活动,将所有数据存储在临时表中,然后通过临时表(未索引)查找所有项目没有activity_id,而在我的版本中,它只通过实体表过滤掉没有关联活动的元素。
【解决方案2】:

听起来您想从 u_entities 中选择 u_activities 中不存在任何行的所有内容。这样做的方法是使用子查询,而不是任何类型的连接。这是一种方法:

SELECT * FROM u_entities
 WHERE entity_id
       NOT IN (SELECT DISTINCT account_id FROM u_activity)

这是另一个:

SELECT * FROM u_entities
WHERE NOT EXISTS (
    SELECT account_id
      FROM u_activity
     WHERE u_activity.account_id = u_entities.entity_id
     LIMIT 1
    )

【讨论】:

  • 谢谢你们所有的查询都很好。 Ted 的第二次查询最快,为 1.29 秒。
  • 为什么我不能接受两个答案?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多