mysql联合vs IN子句
我一直在尝试优化我的一个查询,如下所示:mysql联合vs IN子句,sql,mysql,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.sende
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秒
考虑到我的查询可能会变成50个查询的并集,建议使用多个union子句而不是IN子句。因此,我的查询如下所示:
(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)
按照以下方式重写查询:
SELECT *
FROM MetaTable
WHERE (sender, convid) IN
(
SELECT sender, MAX(convid) as maxconvid
FROM MetaTable
WHERE sender IN ('arjunchow','aamir_alam')
GROUP BY
sender
)
,请确保您在发件人convid上有一个复合索引,并确保它已被i使用。E“解释计划”中有“使用分组索引”选项,请按以下方式重写查询:
SELECT *
FROM MetaTable
WHERE (sender, convid) IN
(
SELECT sender, MAX(convid) as maxconvid
FROM MetaTable
WHERE sender IN ('arjunchow','aamir_alam')
GROUP BY
sender
)
,请确保您在发件人convid上有一个复合索引,并确保它已被i使用。E在解释计划中有一个使用索引的群组,我在标签搜索方面也遇到了类似的问题,实际上我有机会与MySQL技术人员讨论过这个问题;他们建议我创建一个临时表,并在用户之间循环时将我的值添加到该临时表中,然后在该临时表上执行所需的任何操作。任何时候你试图把这么多的东西塞进一个命令中,它都会陷入严重的困境 我在标签搜索方面也遇到了类似的问题,实际上我有机会与MySQL技术人员讨论这个问题;他们建议我创建一个临时表,并在用户之间循环时将我的值添加到该临时表中,然后在该临时表上执行所需的任何操作。任何时候你试图把这么多的东西塞进一个命令中,它都会陷入严重的困境 解释输出会很好。真正了解MySQL的人可能想确认这一点,但在其他SQL平台中,中的代价非常昂贵且不可伸缩,因为解析器必须检查数组中的每个实例。几乎所有用IN完成的事情都可以用exists和/或joins做得更好。。。在MySQL中,子句很好。子查询看不到我的答案。@annakata:子查询在MySQL中不好,因为这个查询:SELECT*FROM long_table LIMIT 1将首先从long table中选择所有内容,然后应用限制。因为@op的查询无论如何都需要子查询中的所有值,所以这里的子查询并不坏。MySQL和四大数据库中的每一个其他RDBMS都能够将谓词推送到IN/NOT IN查询中,将其转换为EXISTS/NOT EXISTS。因为查询在这里是保留键的,所以情况也不是这样。这里最重要的是几乎可以肯定的是,sender、convidAn和EXPLAIN上没有索引输出会很好。真正了解MySQL的人可能会想确认这一点,但在其他SQL平台中,中的代价非常昂贵,而且不可伸缩,因为解析器必须检查数组中的每个实例。几乎所有用IN完成的事情都可以用exists和/或joins做得更好。。。在MySQL中,子句很好。子查询看不到我的答案。@annakata:子查询在MySQL中不好,因为这个查询:SELECT*FROM long_table LIMIT 1将首先从long table中选择所有内容,然后应用限制。因为@op的查询无论如何都需要子查询中的所有值,所以这里的子查询并不坏。MySQL和四大数据库中的每一个其他RDBMS都能够将谓词推送到IN/NOT IN查询中,将其转换为EXISTS/NOT EXISTS。因为查询在这里是保留键的,所以情况也不是这样。这里重要的是几乎可以肯定的是,发送方convid上没有索引