2012-03-25 36 views
3

我有一个包含80百万条记录的表。该表的结构:使用LIKE进行搜索的大型MySQL表的分区

  • ID - 自动增量,
  • 代码 - 从5到100个字符的字母数字代码,
  • 等领域。

最常用的查询是

SELECT * FROM table 
WHERE code LIKE '%{user-defined-value}%' 

查询的数量越来越多,以及在recodrs计数。很快我会遇到性能问题。

有什么办法可以拆分零件中的表格吗?或者也许还有其他方法来优化表格?

回答

2

在搜索领先的%是这里的杀手。它否定了任何索引的使用。

我能想到的唯一事情就是根据代码长度对表进行分区。

例如,如果输入的代码长度为10个字符,则首先使用10个字符代码搜索表格,而不使用前导百分号,然后使用11个字符代码搜索带有前导百分号的表格,以及然后是带有12个字符代码的表格,带有百分号,等等。

这使您无需搜索长度小于10个字符且永远不会匹配的所有代码。此外,您可以使用索引进行其中一项搜索(第一项)。

这也有助于保持表格尺寸略小。

尽管您可能想动态创建查询,但您可以使用UNION一次执行所有查询。

您还应该看看FULLTEXT索引可能是更好的解决方案。

+0

其实,我已经添加了另一列“code_inverted”来解决领先的“%”问题。 我会尝试按照您的建议按代码长度拆分表格。 – Leksat 2012-03-25 12:07:34

+0

不错。请注意,code_inverted只有在没有结尾%(即成为新的前导%)时才会解决带有前导%的问题。 :) – Ami 2012-03-25 12:20:48

0

的几点思考:

  1. 您可以将表格分成基于一定条件的多个较小的表。例如,在ID可能或可能是code或可能是任何其他字段。这基本上意味着你保持某种类型的表中的记录和分离不同类型分成不同的表

  2. 尝试MySQL Partitioning

  3. 如果可能的话。清除旧条目,或者您可能至少把它们移动到另一个存档表

  4. 代替LIKE的,可以考虑使用REGEXP的正则表达式搜索

  5. 而不是运行SELECT *,试着只选取选择性列SELECT id, code, ...

  6. 我不确定此查询是否与您的应用程序中的某个搜索有些相关,其中用户输入的值与code列进行比较,并将结果回显给用户。但是,如果是的话,您可以尝试在搜索查询中添加选项,例如询问用户是否想要完全匹配或者应该从匹配开始。这种方式您不一定每次都需要运行LIKE匹配

  7. This应该是第一点,但我认为你在表格上有正确的索引

  8. 尝试使用更多的查询缓存。使用它的最好方法是避免频繁更新表,因为每次更新都会清除查询缓存。所以更少的更新,更可能是MySQL缓存查询,这将意味着更快的结果

希望以上帮助!

+0

一些好点。为了澄清,REGEXP在性能方面不会比LIKE好(可能更糟糕)。查询缓存仅用于搜索相同的地方。 – Ami 2012-03-25 12:26:54

相关问题