使用IN(...)是随机访问MySQL表的最有效方法吗?

时间:2009-05-07 14:26:37

标签: sql mysql

我有一个2.4M +行的表,没有索引。我100%确定所有行都有一列(我们称之为id),这是唯一的,类型为VARCHAR(255)

我现在有一个大约10,000 id的文件,需要为每个文件拉出整行。

使用IN(...)是我最好的选择吗?我应该添加索引吗?

我在想一些像这样的事情:

SELECT * FROM archive_table WHERE id IN('id1', 'id2', ... 'idn');

这是有效的归档数据,每隔几周我才能访问。


系统:MySQL 5.0.45 表:MyISAM

5 个答案:

答案 0 :(得分:3)

由于您有一个所需的ID文件,我建议将其导入工作表,然后将表连接到生产表以获得所需的结果。当然,在你做任何事情之前,你需要实现一个索引策略。

答案 1 :(得分:2)

在ID列上添加索引,并(可选)将其定义为UNIQUE。 这将有助于MySQL快速找到您想要的行,因为索引包含按排序顺序排列的ID。即使你的桌子也被分类了,e。 G。因为你按递增的ID顺序插入,MySQL不知道并且将始终进行全表扫描以查找查询的匹配记录。

另一方面,使用索引,服务器的搜索变得非常容易。只有当你一次要求真正的,非常多的行(非常长的IN()子句)时,优化器可能会决定你需要超过30%的数据 - 在这种情况下它会再次回到线性扫描防止过多的磁盘搜索。

然而,有数百万行,这将是一个很长的条件:)

我还建议重新考虑列是否真的必须长度为255个字符 - 即使VARCHAR在你不需要时也不会使用那么多空间,这听起来像是一个有问题的设计。它是否应该是数字字段可能取决于您的需求,但通常建议使用。

答案 2 :(得分:0)

天啊,你应该添加一个索引。但如果id是“主键”,那么它已经是一个索引。

答案 3 :(得分:0)

根据我过去DBA的理解,“IN”子句限制了括号内可以指定的显式ID数。我被告知如果您可以使用SELECT来输入IN列表,则不适用。

HLGEM关于导入和使用联接的建议可能是最简单的方法。而且,如前所述,索引将提高性能。

答案 4 :(得分:0)

是的,在两个表上添加一个索引(2.4mil和10,000)。

假设transaction_table是10,000行,archive_table是2.4mil行,你已经建立了一个索引overr archive_table你可以编码:

SELECT id
  FROM transaction_table a
 WHERE EXISTS( SELECT *
                 FROM archive_table b
                WHERE a.id = b.id )

在JOIN上使用EXISTS子句更具可读性,并且具有与连接相同的性能。