我有一个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
答案 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子句更具可读性,并且具有与连接相同的性能。