Jon*_*nas 15 mysql optimization wildcard
How can queries like
SELECT * FROM sometable WHERE somefield LIKE '%value%'
Run Code Online (Sandbox Code Playgroud)
be optimized?
The main issue here is the first wildcard which prevents DBMS from using index.
Edit: What is more, somefield value is solid string (not a piece of text) so fulltext search could not be performed.
Tim*_*imo 21
你的琴弦有多长?
如果它们相对较短(例如英文单词; avg_len = 5)并且您有备用数据库存储,请尝试以下方法:
value
给出:
value
alue
lue
ue
e
LIKE 'alu%'
(将'alu'作为'value'的一部分)来搜索子字符串.通过存储所有后缀,您无需使用前导通配符(允许使用索引进行快速查找),但需要以存储空间为代价.
存储成本
存储单词所需的字符数word_len*word_len / 2
在每个单词的基础上变为字长的二次方.以下是各种单词大小的增加因素:
(3*3/2) / 3 = 1.5
(5*5/2) / 5 = 2.5
(7*7/2) / 7 = 3.5
(12*12/2) / 12 = 6
存储单词所需的行数从1增加到word_len
.注意这个开销.应将其他列保持在最低限度,以避免存储大量冗余数据.例如,最初找到该单词的页码应该没问题(想想unsigned smallint),但是单词上的大量元数据应该基于每个单词而不是每个后缀存储在单独的表中.
注意事项
在我们分割"单词"(或片段)的地方存在权衡.作为一个现实世界的例子:我们用连字符做什么?我们将形容词存储five-letter
为一个或两个单词吗?
权衡如下:
five
和letter
单独存储,搜索five-letter
或fiveletter
将失败.为方便起见,您可能希望删除连字符和存储fiveletter
.这个词现在可以通过搜索发现five
,letter
和fiveletter
.(如果您也从任何搜索查询中删除连字符,用户仍可以成功找到five-letter
.)
最后,有一些存储后缀数组的方法不会产生太大的开销,但我还不确定它们是否可以很好地转换为数据库.
两种方式:
(1)使用内存中的表,它可以非常快速地运行。
(2)制定比更好的索引和搜索算法foo LIKE '%bar%'
。如果不了解您的问题,就不可能对此提出任何建议。
正如您所指出的那样,%bar%模式可确保对每个查找进行表扫描,从而使数据库软件中任何可能的搜索独创性都无效。