ero*_*ppa 8 mysql sql full-text-search query-optimization
我们这里有一个简单的SQL问题.在varchar列中,我们希望在字段中的任何位置搜索字符串.实现此性能的最佳方法是什么?显然,一个指数在这里没有任何帮助,其他任何技巧?
我们使用MySQL并拥有大约300万条记录.我们需要每秒执行许多这些查询,因此我们真正尝试以最佳性能实现这些查询.
到目前为止,最简单的方法是:
Select * from table where column like '%search%'
Run Code Online (Sandbox Code Playgroud)
我应该进一步指定该列实际上是一个长字符串,如"sadfasdfwerwe",我必须在此列中搜索"asdf".所以他们不是句子而是试图匹配他们中的一个词.全文搜索仍然有用吗?
Bil*_*win 15
查看我的演示文稿MySQL中的实用全文搜索.
我比较了:
LIKE 谓词LIKE)今天我将使用的是Apache Solr,它将Lucene置于一项带有一系列额外功能和工具的服务中.
你的评论:啊哈,好吧,不.我提到的全文搜索功能都没有帮助,因为它们都假设某种词边界
有效地找到任意子串的另一种方法是N-gram方法.基本上,创建N个字母的所有可能序列的索引,并指向每个相应序列出现的字符串.通常,这是通过N = 3或三元组来完成的,因为它是匹配较长子串并将索引保持在可管理大小之间的折衷点.
我不知道任何透明地支持N-gram索引的SQL数据库,但您可以使用倒排索引自己设置它:
create table trigrams (
trigram char(3) primary key
);
create table trigram_matches (
trigram char(3),
document_id int,
primary key (trigram, document_id),
foreign key (trigram) references trigrams(trigram),
foreign key (document_id) references mytable(document_id)
);
Run Code Online (Sandbox Code Playgroud)
现在用艰难的方式填充它:
insert into trigram_matches
select t.trigram, d.document_id
from trigrams t join mytable d
on d.textcolumn like concat('%', t.trigram, '%');
Run Code Online (Sandbox Code Playgroud)
当然这需要一段时间!但是一旦完成,你可以更快地搜索:
select d.*
from mytable d join trigram_matches t
on t.document_id = d.document_id
where t.trigram = 'abc'
Run Code Online (Sandbox Code Playgroud)
当然你可以搜索超过三个字符的模式,但倒排索引仍然有助于缩小你的搜索范围:
select d.*
from mytable d join trigram_matches t
on t.document_id = d.document_id
where t.trigram = 'abc'
and d.textcolumn like '%abcdef%';
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5997 次 |
| 最近记录: |