关于索引:mysql查询中如何使用索引效率 | 珊瑚贝

How to use index efficienty in mysql query


我的数据库在 mysql v5.x 上运行。我有一个包含 5 列的表 T1,列 C1 是主键。 C1 是 varchar(20) 类型。它包含大约 2000 行,其值如下:

1
2
3
4
fxg
axt3
tru56
and so on..

现在我的应用程序的工作是读取输入数据并查找输入数据的起始模式是否类似于表 T1 中的 C1 列中的起始模式。例如:我的输入可能显示为:

1
2
3
4
5
    trx879478986
    fxg87698x84
    784xtr783utr
    axt3487ghty
and so on

所以对于上述输入,我必须为 \\’fxg87698x84\\’ 和 \\’axt3487ghty\\’ 返回 true,而对于其他输入则返回 false。我使用的查询是:

1
2
select 1 from T1 where (? like concat(C1,%));
note: the ? is replaced by the input value got from the application.

问题是我的输入量很大(大约 100 万条记录要在 30 分钟内处理),而且我的查询速度不够快。关于如何重写查询或强制它使用索引的任何想法?即使我必须使用不同的对象结构,我也可以做到,如果有帮助的话。因此,任何帮助将不胜感激。谢谢。


您可以尝试使用 Top-N 查询来查找第一个候选者,然后将该候选者仅应用于实际模式:

1
2
3
4
5
6
select 1
  from (select c1
          from junk
         where c1 <= ‘fxg87698x84’
         order by c1 desc limit 1) tmp
 where ‘fxg87698x84’ like concat(c1, %);

top-n 查询应该使用 c1 上的常规索引。

编辑:
在我的博客中更详细地解释了这一点:http://blog.fatalmind.com/2010/09/29/finding-the-best-match-with-a-top-n-query/

  • 美丽的!!。这确实有助于减少我的全表扫描。再次感谢。 – 阿卜杜拉
  • @Abdullah 答案不正确。比较 \\’fxg\\’ <= \\’fxg87698x84\\’ 会返回 1。但比较 \\’exg\\’ <= \\’fxg87698x84\\’ 也会返回 1,无法满足实际要求。


根据您的问题的设置方式,您几乎按照定义需要检查数据库中的每一行,以按照您当前的方式进行操作。在这种情况下,索引并不重要,因为任何行都可以匹配。

我不确定它是否会更快,但您可以尝试的一件事是查询数据库以与您输入的每个可能有效的子字符串完全匹配。

例如,如果您知道子字符串的长度必须至少为 3 才能匹配,请从前 3 个字符开始:
trx879478986 => trx, trx8, trx87, …

构建一个包含这些可能匹配项的数组并使用 IN() 运算符来查询它们:

1
SELECT 1 FROM T1 WHERE c1 IN ($array_of_strings);

我很确定 mysql 可以使用索引来匹配提供给 IN()

的值列表

  • 我要建议的是 – 只有我会添加一个 \\’ORDER BY CHAR_LENGTH (c1)\\’ 来支持 \\’ATX12345\\’ 与 \\’ATX\\’ 的匹配
  • 1,我输入的内容。这确实使用了索引,并且通过避免 LIKE 可以避免如果 C1 包含 % 或 _ 字符会发生什么问题。
  • 谢谢输入。但是我必须做的有效子字符串的组合介于 3 个字符和 20 个字符之间,并且这种额外的处理会抵消我可能获得的性能增益。
  • 你知道这是真的还是你在猜测性能成本?


来源:https://www.codenong.com/3778319/

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?