MySql重复行字符串比较性能

时间:2013-11-21 11:19:20

标签: mysql sql

我有一张包含超过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%'部分运行查询?

1 个答案:

答案 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语法。如果您想要解决一个查询的问题(或者您的列表太长),那么这似乎很有用。