对使用LIKE进行搜索的大型MySQL表进行分区

时间:2012-03-25 10:27:31

标签: mysql partitioning sharding

我有一张包含8千万条记录的表格。表的结构:

  • id - autoincrement,
  • 代码 - 5到100个字符的字母数字代码,
  • 其他领域。

最常用的查询是

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

查询数量和重新计数数量都在增长。很快我就会遇到性能问题。

有没有办法拆分零件中的表格?或者可能还有其他一些方法来优化表格?

2 个答案:

答案 0 :(得分:2)

搜索中的前导%是杀手。它否定了任何索引的使用。

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

例如,如果输入的代码长度为10个字符,则首先使用10个字符代码搜索表,不带前导百分号,然后使用前导百分号在11个字符代码中搜索表,然后包含12个字符代码的表,带有百分号前导,依此类推。

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

这也有助于保持桌面尺寸更小。

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

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

答案 1 :(得分:0)

一些想法:

  1. 您可以根据特定条件将表拆分为多个较小的表。例如,在ID上可能或可能是code或可能是任何其他字段。它基本上意味着您在表中保留某种类型的记录,并将不同类型分成不同的表

  2. 尝试MySQL Partitioning

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

  4. 考虑使用REGEXP进行正则表达式搜索

  5. ,而不是LIKE
  6. 尝试仅选择选择性列SELECT *

  7. ,而不是运行SELECT id, code, ...
  8. 我不确定此查询是否与您的应用程序中的搜索有些关联,其中用户输入的值与code列进行比较,结果回显给用户。但如果是,您可以尝试向搜索查询添加选项,例如询问用户是否需要完全匹配或者应该从匹配开始等。这样您不一定每次都需要运行LIKE匹配

  9. 这应该是第一点,但我假设你在桌子上有正确的索引

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

  11. 希望以上有所帮助!