Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql联合vs IN子句_Sql_Mysql - Fatal编程技术网

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上没有索引