【问题标题】:MySQL Stored Procedure, Memory Temporary Table too slow?MySQL存储过程,内存临时表太慢?
【发布时间】:2012-11-19 03:31:36
【问题描述】:

我正在尝试在 MySQL 中编写存储过程。由于复杂的原因,我有一个带有一堆连接的聚合查询来查看对象 ID,然后使用更多连接(包括相同的表)执行另一个查询以获取一些数据

所以,是这样的:

CREATE TEMPORARY TABLE ids ENGINE=MEMORY
SELECT MAX(child.id)
    FROM parent 
    JOIN child ON child.parent_id = parent.id
    WHERE
    GROUP BY child.parent_id;

SELECT *
    # MUST SELECT STUFF FROM PARENT, CHILD, AND STUFF JOINED ON CHILD
    FROM child 
    JOIN parent ON parent.id = child.parent_id
    # A BUNCH MORE JOINS HERE
    WHERE child.id IN (SELECT * FROM ids);

DROP TEMPORARY TABLE  IF EXISTS ids;

现在我注意到第一次选择需要 0.000 秒。第二次选择,如果我将 (SELECT * FROM ids) 替换为像 (1435,2352,43653,34534,...) 这样的常量列表,也需要 0.000 秒。

但是,使用临时表创建运行它们需要 0.6 秒。 0.o WTH?

所以我的问题是如何跳过这个临时表创建,只传递 id 列表?

另外,如果我将整个第一个选择作为子选择移动到第二个选择,那么整个过程需要更长的时间。超过一分钟后我放弃等待。

【问题讨论】:

  • 你看过/试过UNION吗?或者也许我错过了临时表的原因......
  • 我看不出这有什么帮助。
  • 那么可能需要澄清一下,因为我不确定我是否理解您要做什么。

标签: mysql stored-procedures temp-tables


【解决方案1】:

试试这个:

SELECT *
FROM (
  SELECT parent.*, MAX(child.id) as max_id
  FROM parent 
  JOIN  child ON child.parent_id = parent.id
  WHERE -- some where cond
  GROUP BY parent.id
) as parents
JOIN  child ON child.id = parents.max_id
-- other joins

并显示性能结果。

【讨论】:

  • 你的意思是 JOIN child on child.id = parents.max_id 当然?
  • 又糊涂了。内部选择需要与子连接,否则我无法调用 MAX(child.id)..
  • 试过了。有用。我加入父母和孩子两次,但查询以 0.000 运行。 :)
  • 是的,你说的完全正确,我在重写时一定忽略了这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 2018-02-20
  • 2013-09-15
相关资源
最近更新 更多