SQL NOT IN [id列表](性能)

时间:2012-06-22 19:51:16

标签: mysql

我只是想知道列表中id的数量是否会影响查询性能。

查询示例:

SELECT * FROM foos WHERE foos.ID NOT IN (2, 4, 5, 6, 7)

(2, 4, 5, 6, 7)是一个无限增长的列表。

有多少(在订单的背景下)?

更新:之所以我问它是因为我有两个数据库。它(只读)是项目的来源,另一个包含由操作员处理的项目。每当操作员从只读db请求新项目时,我想要排除已经处理的项目。

4 个答案:

答案 0 :(得分:9)

是的,列表中的ID数量会影响性能。例如,网络数据包只是如此之大,数据库必须解析所有噪声并将其转换为一系列:

WHERE foo.ID <> 2
AND foo.ID <> 4
AND foo.ID <> 5
AND ...

您应该考虑其他方法让您的查询了解此集。

答案 1 :(得分:4)

这是一个古怪的重写,可能会执行更好的查询

SELECT * FROM foos
LEFT JOIN
(
    SELECT 2 id UNION
    SELECT 4    UNION
    SELECT 5    UNION
    SELECT 6    UNION
    SELECT 7
) NOT_IDS
USING (id) WHERE NOT_IDS.id IS NULL;

NOT_IDS子查询的工作原理如下所示:

mysql> SELECT * FROM
    -> (
    ->     SELECT 2 id UNION
    ->     SELECT 4    UNION
    ->     SELECT 5    UNION
    ->     SELECT 6    UNION
    ->     SELECT 7
    -> ) NOT_IDS;
+----+
| id |
+----+
|  2 |
|  4 |
|  5 |
|  6 |
|  7 |
+----+
5 rows in set (0.00 sec)

mysql>

答案 2 :(得分:3)

只是为了好玩,并且鉴于您的更新,我将建议一个不同的策略:

您可以像这样加入各个表......

insert into db1.foos (cols) 
  select cols
    from db2.foos src
  left join db1.foos dst
    on src.pk = dst.pk
  where dst.othercolumn is null

我不确定优化器将如何处理这个问题,或者它是否会比你正在做的更快(取决于你的索引策略)。

答案 3 :(得分:0)

db是否在同一台服务器上?如果是,您可以使用左连接进行多数据库查询并获取空连接。 (这里是一个例子:Querying multiple databases at once)。否则,您可以创建一个存储过程,使用字符串传递id,并使用正则表达式将其拆分。我有一个类似的问题,但在内存数据库和postgres数据库中。幸运的是我的情况是(在...中)