我需要在列中执行Contains
操作。对于Contains操作,我们需要在单词之前和之后使用通配符。
Ex:个性化
查询 - >喜欢'%sonal%'
由于此类查询无法使用索引。有没有办法提高搜索速度。
注意:我使用MySql(InnoDB)和PSQL
答案 0 :(得分:4)
PostgreSQL有解决方案 - trigram索引。这是article或documentation
postgres=# create extension pg_trgm ;
CREATE EXTENSION
postgres=# create index on obce using gin (nazev gin_trgm_ops);
CREATE INDEX
postgres=# explain select * from obce where nazev like '%Bene%';
┌──────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Bitmap Heap Scan on obce (cost=20.00..24.02 rows=1 width=41) │
│ Recheck Cond: ((nazev)::text ~~ '%Bene%'::text) │
│ -> Bitmap Index Scan on obce_nazev_idx (cost=0.00..20.00 rows=1 width=0) │
│ Index Cond: ((nazev)::text ~~ '%Bene%'::text) │
└──────────────────────────────────────────────────────────────────────────────┘
(4 rows)
它也适用于正则表达式。
答案 1 :(得分:3)
MySQL支持FULLTEXT indexes。
您可能对我的演示文稿Full Text Search Throwdown感兴趣,我在其中比较了不同的全文索引工具。该演示文稿现在有点陈旧,但其中一些仍然相关。
重新评论:
MySQL的全文索引不支持部分字匹配,尽管它支持有限的通配符,但仅限于模式的末尾。而全文的InnoDB实现并不支持它,只有MyISAM才支持它。请参阅https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html
中提到的*
通配符
SELECT ... WHERE MATCH(mycolumn) AGAINST ('stack*' IN BOOLEAN MODE)
弹性搜索也支持通配符,但是像MySQL一样,如果您的通配符位于模式的开头,它们就不会有效。见https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
Sphinx Search支持中缀字符串索引选项。如果将min_infix_len
设置为非零正数,它将索引所有中缀子字符串以及整个单词。
见http://sphinxsearch.com/docs/current.html#conf-min-infix-len
答案 2 :(得分:3)
如果你需要在值的任何位置找到任何char序列,我想没有逻辑优化。如果当前查找需要几秒钟,那么您可以从使用外部优化索引中受益,如下所示:
添加2个额外列:offset
带索引,length
无索引。
将所有值加入单个文本文件中,并在每行中保存偏移量和长度。
编写一个外部工具在整个文件中进行搜索(使用strstr()
之类的内容)并返回偏移量。
使用返回偏移来标识SELECT TOP 1 FROM table WHERE offset < @offset ORDER BY offset DESC
之类的行。
使用length
字段确保匹配的片段在记录之间不存在:@offset + @length
(搜索到的字符串的结尾)是<= offset + length
(结束时)找到的行上的值。)
您还可以将完整的连接文本保存在数据库中的全局变量或专用表中,以避免产生外部进程或访问磁盘。