如果您的目标是测试MySQL列中是否存在字符串(类型为'varchar','text','blob'等),以下哪一项更快/更有效/更好用,以及为什么?
或者,是否还有其他方法可以超越其中任何一种?
INSTR( columnname, 'mystring' ) > 0
VS
columnname LIKE '%mystring%'
答案 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
结果
LIKE
或INSTR
肯定比REGEXP
快。
虽然最小,缓存时序差异可能足以进一步调查。
在可能配置的MySQL系统上,全文索引通常应该总是更快或至少与非索引搜索相同。因此,无论间歇性标记代码如何,都要使用索引,尤其是长人类语言文本。