我的Mysql LIKE语句有多快?

时间:2012-04-15 19:50:08

标签: mysql database full-text-search query-optimization sql-like

以下MYSQL语句需要0.577251秒:

SELECT synonym_group FROM synonym WHERE name LIKE '%ak%'

Name是varchar(250)字段。 同义词数据库表中目前有356,187条记录。 数据:21 MB。索引:23 MB。总大小:45 MB。每行字节数:67。

那么是0.577251秒然后是合理的时间吗?如果没有,那是什么,我应该做什么?我已经在这类问题上阅读了几个主题,我能看到的主要解决方案是使用像sphinx这样的东西。

事实是,我桌子上的几个字段可能是无关紧要的。比方说,如果我将每行的字节数减少一半,通过消除不必要的字段,会使搜索速度提高一倍吗?

提前致谢。

3 个答案:

答案 0 :(得分:5)

如果您使用以LIKE开头的%运算符,则您的选择不会使用任何索引。

所以,是的,时间是正常的。

答案 1 :(得分:4)

如果ak是单词,则FULLTEXT索引可以使用(如果您调整最小单词长度,请参见下文)。

因此,搜索带有FULLTEXT索引的'ak'将匹配:

  • '这是ak那个。'
  • 'AK'
  • 'AK。不管'
  • '无论。 AK'。

然而,它不符合这个:

  • 'BAK'
  • 'AKT'

必须有单词边界才能匹配。

FULLTEXT搜索的默认minimum word length为4个字符。所以,你仍然无法对'ak'进行FULLTEXT搜索,因为它太短了。你可以降低最小字长设置,但你最终会得到'the','和'以及你不想让你的FULLTEXT索引混乱的所有其他三个和更短的字母单词。

使用LIKE搜索可能是您唯一可行的选择。当您使用前导通配符('%ak')时,MySQL无法使用索引来查找记录。它必须扫描所有行。如果你有覆盖索引,它仍将使用索引进行扫描。

因此,对于您的查询:

SELECT synonym_group FROM synonym WHERE name LIKE '%ak%'

如果你在(name, synonym_group)上有一个多列,覆盖,索引,它实际上仍会使用索引来回答查询,但不是传统意义上的。 MySQL将扫描索引,这通常比扫描实际的表数据(表扫描)更快。另外,理想的系统有足够的RAM来存储RAM中的所有索引,所以它只是扫描内存而不是磁盘。

因此,使用覆盖索引,行的大小将无效。

如果没有覆盖索引,行的大小会影响扫描速度,因为磁盘必须移动得更远。

如果最终进行表扫描,则需要对表进行碎片整理,并且最好具有固定长度的行(CHAR而不是VARCHAR)。

答案 2 :(得分:3)

正如juergen所提到的那样,在开头使用%的搜索无法使用您的索引,并且必须扫描整个表格(不好并且只会随着表格大小的增加而变得更糟)。减少列数可能没有用,因为真正的CPU耗尽会在每行中循环通过字符串。

在这种情况下,您应该考虑使用全文搜索和索引:http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html