我有一张包含超过200万条记录的表格, 我需要在列中找到带有字符串类型的重复记录,另外我有这个字段的索引。 我有下一个查询:
select m.* from member as m
where lower(m.username) in
(select lower(b.username) from member as b
where b.Username like 'a%'
group by b.username
having count(b.username) >= 2);
子查询只返回4条记录少于0.2秒,但如果我在条件部分使用它们,这个查询工作时间很长,永远不会返回结果.... 我试图运行下一个查询,理论上是相同的逻辑:
从成员中选择*作为m,其中lower(Username)in(lower('a1'), 下( 'A2'),低级( 'A3'),低级( 'A4'));
它工作得很好而且很快。
问题是什么?
另外我想用where b.Username like 'a%'
部分运行查询?
答案 0 :(得分:1)
在一般情况下,MySQL无法使用IN
子查询的索引
这很难过,但实际上,MySQL无法识别“常量子查询”。这是什么意思?这意味着如果你有一个返回静态值列表的子查询 - 并且你在另一个查询中的IN
中使用它,那么MySQL 将不会使用索引(通过范围内)。
为什么会这样?
实际上,最正确的一点是 - 因为MySQL会处理以下查询:
.. WHERE `field` IN ('foo', 'bar', 'baz')
和
.. WHERE `field` IN (SELECT `col` FROM t)
-as 不同的查询(我假设第二个查询中表col
中的列t
具有相同的值,即'foo', 'bar', 'baz'
)。第一个查询等同于它的“预期”情况,即值范围。但是= ANY
subquery的第二个查询是相同的 - 所以MySQL不会使用索引。
怎么做
实际上,您的案例和案例类似 - 最好将您的查询分成两部分。第一部分将从您的表中检索静态值列表。第二部分将第一部分的结果替换为IN
子句,然后您将使用。
替代方案 - 您可以对表使用JOIN
语法。如果您想要解决一个查询的问题(或者您的列表太长),那么这似乎很有用。