高效的数据库搜索LIKE'%something%'

时间:2010-10-07 23:00:01

标签: sql

我正在尝试在电话号码中搜索包含一系列数字的任何电话号码。

显然以下情况会很慢:

 Select * from customer where phone like '%1234%'

我需要通配符,因为允许用户输入数据库中的任何数据,因此它可能包含国家/地区代码,前导1(如1-800)或尾随扩展(有时仅由a分隔空间。

注意:我已经通过删除所有非数字字符创建了“已清理”的电话号码,因此我不必担心破折号,空格等。

让这样的搜索在合理的时间内运行有什么魔力吗?

2 个答案:

答案 0 :(得分:2)

如果您使用的是MySQL,那么您正在寻找全文搜索功能http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html

它专门优化了您列出的查询,并且一旦设置就非常快速。您需要MySQL中的数据,它必须位于MyISAM表中(不是InnoDB或其他。)

我在生产中使用它并且效果很好。

答案 1 :(得分:1)

不。

如果您愿意,可以制作索引表。它会有点贵,但也许值得。

所以你可以把一个电话号码:2125551212转换成基于唯一子串的数百个引用并构建一个倒排索引:

1
2
5
12
21
25
51
55
121
125
212
255
512
551
555
1255
2125
2555
5121
5512
5551
12555
21255
25551
55121
55512
125551
212555
255512
555121
1255512
2125551
2555121
12555121
21255512
212555121
2125551212

所以,例如:

create table myindex (
    key varchar(10) not null,
    datarowid integer not null references datarows(id)
);
create index i1myindex(key);
insert into myindex values('1255', datarow.id);

取决于你想要的深度。

例如,你只能深入4,然后扫描4个数字的结果。

因此,例如,如果您有“%123456%”,则可以请求带有“1234”的键,然后在结果集上应用完整表达式。

像:

select d.* from datarows d, myindex i where i.datarowid = d.id and i.key = '1234' and d.phone like "%123456%";

索引应该可以帮助您快速缩小批次范围,数据库将扫描剩余部分。

显然,你会在这里生成一些数据,但如果你经常查询,你可以在这里做一些表现。