2012-11-30 60 views
0

我正试图在MySQL中编写一个存储过程。对于复杂的原因,我有一堆汇总查询的连接来看看对象ID,然后做另一个查询更多的连接(包括相同的表),以获得一些数据MySQL存储过程,内存临时表太慢?

所以,这样的事情:

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秒。如果我用(1435,2352,43653,34534,...)等常数列表替换(SELECT * FROM ids),则需要0.000秒。

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

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

此外,如果我将整个第一次选择作为子选择移动到第二次选择,那么整个过程将花费更长的时间。一分钟以上,我放弃等待。

+0

你看过/试过'UNION'吗?或者,也许我错过了临时表的原因... – Benjam

+0

我不明白这会有什么帮助。 – McTrafik

+0

也许需要澄清一下,因为我不确定我是否理解你正在尝试做什么。 – Benjam

回答

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 

和显示性能结果。

+0

你的意思是JOIN child on child.id = parents.max_id当然? – McTrafik

+0

是的,我已经纠正了这一点,thanx指出了这一点 – piotrekkr

+0

再次混淆。内部选择需要与孩子加入,否则我不能调用MAX(child.id)。 – McTrafik