mysql UNION vs IN子句

时间:2009-06-09 10:12:47

标签: sql mysql

我一直在尝试优化我的一个查询,如下所示:

select toc.* from
    (select sender, max(convid) as maxconvid
     from MetaTable 
     where sender in ('arjunchow','aamir_alam')
     group by sender) as tmp1
    inner join MetaTable as toc on 
        toc.sender = tmp1.sender 
        and toc.convid = tmp1.maxconvid;

当mysql服务器处于压力之下时,此查询通常会在0.2秒内响应,但是当IN子句中“发送方”ID的数量增加(> 50)时,查询速度会非常慢(~5-6秒) )。

建议使用多个union子句而不是IN子句,因为我的查询可能会成为50个查询的并集。所以我的查询看起来像:

(SELECT 
    convId, 
    UNIX_TIMESTAMP(timeStamp) as timeStamp, 
    UNIX_TIMESTAMP(createTime) as createTime, 
    numMessages, 
    rootMsg, 
    sender, 
    ipormobile, 
    modIpOrMobile, 
    UNIX_TIMESTAMP(modTimeStamp) as modTimeStamp 
 from 
    MetaTable 
 where 
    sender='arjunchow' 
 ORDER BY convId DESC limit 1) 
UNION ALL 
(SELECT 
    convId, 
    UNIX_TIMESTAMP(timeStamp) as timeStamp, 
    UNIX_TIMESTAMP(createTime) as createTime, 
    numMessages, 
    rootMsg, 
    sender, 
    ipormobile, 
    modIpOrMobile, 
    UNIX_TIMESTAMP(modTimeStamp) as modTimeStamp 
 from 
    MetaTable 
 where 
    sender='aamir_alam' 
 ORDER BY convId DESC limit 1)

2 个答案:

答案 0 :(得分:1)

我在标签搜索方面遇到了类似的问题,实际上有机会与MySQL技术人员讨论这个问题;他们建议我创建一个临时表,并在循环访问用户时将值添加到该表中,然后在该临时表上执行所需的任何操作。每当你试图把这么多包装成一个命令时,它就会严重陷入困境。

答案 1 :(得分:0)

重写您的查询,如下所示:

SELECT  *
FROM    MetaTable
WHERE   (sender, convid) IN
        (
        SELECT  sender, MAX(convid) as maxconvid
        FROM    MetaTable
        WHERE   sender IN ('arjunchow','aamir_alam')
        GROUP BY
                sender
        )

,确保在(sender, convid)上有一个综合索引,并确保它已被使用(即解释计划中有USING INDEX FOR GROUP BY