【问题标题】:MySQL Select from UNION performance issue (kills database)MySQL Select from UNION 性能问题(杀死数据库)
【发布时间】:2014-05-15 11:35:33
【问题描述】:

我有一点关于 MySQL 的问题

我正在尝试像这样创建两个表的 UNION:

SELECT `user_id`, `post_id`, `requested_on`
   FROM `a` 
      WHERE `status` != 'cancelled' 

UNION 

SELECT `user_id`, `post_id`, `time` as requested_on 
   FROM `b` 
      WHERE `type` = 'ADD' 

这个查询在Showing rows 0 - 29 (36684 total, Query took 0.0147 sec)中执行

但是当我这样做时

SELECT * FROM (
   SELECT `user_id`, `post_id`, `requested_on`
      FROM `a` 
         WHERE `status` != 'cancelled' 

   UNION 

   SELECT `user_id`, `post_id`, `time` as requested_on 
      FROM `b` 
         WHERE `type` = 'ADD' 
) tbl1

MySQL 死了。

之所以要这么做,是为了GROUP BY user_id, post_id

任何想法为什么会发生这种情况/任何解决方法?

稍后编辑:

这是 SQL 小提琴:

http://sqlfiddle.com/#!2/c7f82d/2

最后的查询就在那里,执行于:

Record Count: 10; Execution Time: 574ms

在我看来,10 条记录的 574 毫秒是巨大的。

【问题讨论】:

  • 你能提供一个sqlfiddle吗?您希望最终结果中的哪个requested_on
  • 请显示您要执行的最终查询。表上存在哪些索引?
  • 死亡,你的意思是你的查询需要很长时间来执行/使用大量的 IO / CPU?此外,Showing rows 0 - 29 (36684 total... 意味着初始查询返回一个小子集,而第二个派生表需要对GROUP 进行整体评估
  • 这是小提琴:sqlfiddle.com/#!2/c7f82d/2 小提琴有效,但在我的本地实例和服务器上它只是死了。死亡意味着需要很长时间才能执行(我不知道多少,但可能超过 10 分钟)
  • 最后的查询在小提琴中,我只想分组 user_id, post_id BOTH Tables。我的服务器版本:5.5.37-0ubuntu0.14.04.1 - (Ubuntu),服务器版本:5.5.33 - Remi 的 MySQL Community Server (GPL)

标签: mysql sql group-by subquery union


【解决方案1】:

我找到了问题所在。

事实上,我在 PHPMyAdmin 中运行查询,当我执行 SELECT UNION SELECT 时,一切都很好,但是当我执行 SELECT * FROM (SELECT UNION SELECT) PHPMyAdmin 的分页系统失败,PHPMyAdmin 试图向我的浏览器输出超过 30k 行的表,这就是 SQL 请求挂起的原因。 :(

【讨论】:

    【解决方案2】:

    不清楚是什么问题:

    SELECT * FROM (
       SELECT user_id, post_id, requested_on
          FROM a
             WHERE status != cancelled
       UNION 
       SELECT user_id, post_id, time as requested_on 
          FROM b 
             WHERE type = ADD 
    ) tbl1 GROUP BY user_id, post_id
    

    的意思。假设你有:

    A, x, t1 A, x, t2

    你想要有 t1 还是 t2 的那一行?如果没关系,让我们应用一个聚合函数,例如 MIN:

    SELECT user_id, post_id, MIN(requested_on) FROM (
       SELECT user_id, post_id, requested_on
       FROM a
       WHERE status <> cancelled
       UNION 
       SELECT user_id, post_id, time as requested_on 
       FROM b 
       WHERE type = ADD 
    ) tbl1 
    GROUP BY user_id, post_id
    

    MySQL 通常不能很好地处理这样的派生表,还有其他谓词可以应用于联合中的部分吗?

    【讨论】:

    • 感谢您的宝贵时间,我从哪里找到了问题所在。事实上,我在 PHPMyAdmin 中运行查询,当我执行 SELECT UNION SELECT 时一切都很好,但是当我执行 SELECT * FROM (SELECT UNION SELECT) 时,PHPMyAdmin 的分页系统失败了,PHPMyAdmin 试图输出到我的浏览器超过 30k 行的表,这就是 SQL 请求挂起的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 2012-11-21
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2011-10-04
    相关资源
    最近更新 更多