哪个更快 - INSTR或LIKE?

时间:2010-03-16 01:38:42

标签: mysql sql-like

如果您的目标是测试MySQL列中是否存在字符串(类型为'varchar','text','blob'等),以下哪一项更快/更有效/更好用,以及为什么?

或者,是否还有其他方法可以超越其中任何一种?

INSTR( columnname, 'mystring' ) > 0

VS

columnname LIKE '%mystring%'

4 个答案:

答案 0 :(得分:48)

FULLTEXT搜索绝对会更快,正如kibibu在上面的评论中指出的那样。

然而

mysql> select COUNT(ID) FROM table WHERE INSTR(Name,'search') > 0;
+-----------+
| COUNT(ID) |
+-----------+
|     40735 | 
+-----------+
1 row in set (5.54 sec)

mysql> select COUNT(ID) FROM table WHERE Name LIKE '%search%';
+-----------+
| COUNT(ID) |
+-----------+
|     40735 | 
+-----------+
1 row in set (5.54 sec)

在我的测试中,它们表现完全相同。它们都是不区分大小写的,通常它们执行全表扫描,在处理高性能MySQL时通常是禁止的。

除非您在索引列上进行前缀搜索:

mysql> select COUNT(ID) FROM table WHERE Name LIKE 'search%';
+-----------+
| COUNT(ID) |
+-----------+
|         7 | 
+-----------+
1 row in set (3.88 sec)

在这种情况下,只有后缀通配符的LIKE要快得多。

答案 1 :(得分:11)

MySQL - INSTR vs LOCATE vs LIKE vs REGEXP

对我而言, INSTR LOCATE 表现最快:

# 5.074 sec
SELECT BENCHMARK(100000000,INSTR('foobar','foo'));

# 5.086 sec
SELECT BENCHMARK(100000000,LOCATE('foo','foobar')); 

# 8.990 sec
SELECT BENCHMARK(100000000,'foobar' LIKE '%foo%');

# 14.433 sec
SELECT BENCHMARK(100000000,'foobar' REGEXP 'foo'); 

# 5.5.35-0ubuntu0.12.10.2 
SELECT @@version;

答案 2 :(得分:10)

如果是“前wilcard”(即“LIKE'%...'”谓词),就像这里的情况一样, INSTR和LIKE应该执行大致相同的

当通配符为“前通配符”时,LIKE方法应该更快,除非通配符不是非常有选择性。

为什么通配符的类型及其选择性重要的原因是具有INSTR()的谓词将系统地导致表扫描(SQL无法做出任何假设INSTR的语义,SQL可以利用它对LIKE谓词语义的理解,使用索引来帮助它只测试一组减少的可能匹配。

根据问题本身的评论中的建议,全文索引会更快。差异取决于文本中单词的具体分布,以及整体表格大小等,但期望从快两倍到可能快10倍。

除了创建这样一个索引的一般开销之外,使用全文索引的一个可能的缺点是,除非在配置此索引时非常小心(例如:定义停用词列表,使用特定的搜索语法来避免屈折形式等......),可能存在FullText提供的结果不符合预期的情况。例如,搜索“SAW”(切割木材的工具),可以获得大量的记录,包括动词“to see”,以其各种共轭形式。
当然,全文索引的这些语言感知特征通常可以被覆盖,并且人们可以认为这些特征实际上是有利的,而不是缺点。我在这里提到这个,因为我们将它与普通的通配符搜索进行比较。

答案 3 :(得分:3)

razzed的测试几乎没有什么可补充的。但显然使用 regexp确实会产生更大的处理负担,这与 Seth 在评论中指出的不同。

以下测试假设您在my.ini

中将query_caching设置为On
query_cache_type = 1
query_cache_size = 64M

<强>测试

  • 时间显示三次测量中的平均性能(间歇性地清除缓存):

  • LIKE

    SELECT * FROM `domain_model_offers` WHERE `description` LIKE '%inform%' LIMIT 0 , 30
    

    首字母:0.0035s
    缓存:0.0005s

  • REGEXP

    SELECT * FROM `domain_model_offers` WHERE `description` REGEXP 'inform' LIMIT 0 , 30
    

    初始:0.01s
    缓存:0.0004s

结果

LIKEINSTR肯定比REGEXP快。

虽然最小,缓存时序差异可能足以进一步调查。

在可能配置的MySQL系统上,全文索引通常应该总是更快或至少与非索引搜索相同。因此,无论间歇性标记代码如何,都要使用索引,尤其是长人类语言文本。