问题1:////////////////////////////////////////公司目前有一个需求在10W左右的数据上 对一字段(varchar) 实现 :模糊快速 检索。说下我目前做的一些实验(没用过Oracle,但是请大家给点意见,数据库的原理都差不多!):mysql5:对该 字段 建立索引: 查询 like '%NNN' 在java程序上用时 50ms(毫秒)左右 sql2000:对该 字段 建立索引: 查询 like '%NNN' 在java程序上用时 40ms左右 对该 字段 建立全文索引:可以实现模糊查询 在java程序上用时 100ms左右 lucene : 对该 字段 建立索引(并保存所有数据) 可以实现模糊查询 在java程序上用时 170ms左右
领导说效率太低了:领导希望在 该数据量(10W+)下模糊查询:10ms以下 模糊查询的定义: 如: 输入 “北京 + 空格 + 商场” 把包含 北京 和 商场 (北京 和 商场 的位置可前可后——可互换位置) 的数据都查出:(4) 如果将 北京 和 商场 给索引了(2列数据) 怎么查出 都包含 北京和商场的对应数据
领导给我一个建议(索引表——我不了解是什么):他给我解释是: 先将 该字段 分词 建立一个表(table2) ,再在table2上做索引,然后再搜索。我是一个才毕业的学生,因为水平有限,请各位前辈都给点指点和意见!您的回答:1:10W+数据量下 10ms以下 的模糊查询(如上解释)是否能否实现?2:如果1能实现,实现的方法是?(如果能够自信请仔细点)3:其他方法建议(可能提高数据检索的速度和实现模糊查询功能)!!!4:(4如上标注)怎么实现?希望各位前辈和朋友不吝赐教!不会的朋友也可以学学数据检索方面的知识。来给意见和回答的朋友都给分,分不够则加。。希望都来说一下!!我都弄了2个星期了,还是没什么眉目!!再次谢谢 各位了!! 问题1结束////////////////////////////////////////////////////问题2:///////////////////////////////////////////////////////////
现在的状态:
原始数据表(dataTable) 27000+的数据
目前我又前进了一点了,我先用一个分词器,将该表中的该字段给做了 分词,然后将分词后的内容存入 table2(keyName{单个词元},strId)在 keyName上做了索引,strId是 类似 12,45,365,789 用逗号分隔的id的字符串,就是将含有keyName词元的dataTable的id字段保存进来到时候搜索的时候就 select * from table2 where keyName in('北京','商场');然后程序判断,strid取出来做匹配,有相同id的取出来,再到dataTable取,
目前速度大概是20ms,最快10ms(但是可能性很小,1%不到) (查询用时 是在java程序中println出来的,在数据库中不知道怎么查看精确到ms的查询时间)今天给领导看了,说还不行,说效率还可以提高10倍左右(大概也就是2ms?)我现在已经不知道还要怎么做了(他说在table2上在做索引)!(这个再做索引,该怎么弄下去啊?):请各位给点再优化的方法或者意见!问题2结束//////////////////////////////////////////////////////////各位,我知道我说的不是很清楚,!有什么不清楚的地方请直言!以上2个问题随便回答一个都可以!希望能够得到帮助!
领导说效率太低了:领导希望在 该数据量(10W+)下模糊查询:10ms以下 模糊查询的定义: 如: 输入 “北京 + 空格 + 商场” 把包含 北京 和 商场 (北京 和 商场 的位置可前可后——可互换位置) 的数据都查出:(4) 如果将 北京 和 商场 给索引了(2列数据) 怎么查出 都包含 北京和商场的对应数据
领导给我一个建议(索引表——我不了解是什么):他给我解释是: 先将 该字段 分词 建立一个表(table2) ,再在table2上做索引,然后再搜索。我是一个才毕业的学生,因为水平有限,请各位前辈都给点指点和意见!您的回答:1:10W+数据量下 10ms以下 的模糊查询(如上解释)是否能否实现?2:如果1能实现,实现的方法是?(如果能够自信请仔细点)3:其他方法建议(可能提高数据检索的速度和实现模糊查询功能)!!!4:(4如上标注)怎么实现?希望各位前辈和朋友不吝赐教!不会的朋友也可以学学数据检索方面的知识。来给意见和回答的朋友都给分,分不够则加。。希望都来说一下!!我都弄了2个星期了,还是没什么眉目!!再次谢谢 各位了!! 问题1结束////////////////////////////////////////////////////问题2:///////////////////////////////////////////////////////////
现在的状态:
原始数据表(dataTable) 27000+的数据
目前我又前进了一点了,我先用一个分词器,将该表中的该字段给做了 分词,然后将分词后的内容存入 table2(keyName{单个词元},strId)在 keyName上做了索引,strId是 类似 12,45,365,789 用逗号分隔的id的字符串,就是将含有keyName词元的dataTable的id字段保存进来到时候搜索的时候就 select * from table2 where keyName in('北京','商场');然后程序判断,strid取出来做匹配,有相同id的取出来,再到dataTable取,
目前速度大概是20ms,最快10ms(但是可能性很小,1%不到) (查询用时 是在java程序中println出来的,在数据库中不知道怎么查看精确到ms的查询时间)今天给领导看了,说还不行,说效率还可以提高10倍左右(大概也就是2ms?)我现在已经不知道还要怎么做了(他说在table2上在做索引)!(这个再做索引,该怎么弄下去啊?):请各位给点再优化的方法或者意见!问题2结束//////////////////////////////////////////////////////////各位,我知道我说的不是很清楚,!有什么不清楚的地方请直言!以上2个问题随便回答一个都可以!希望能够得到帮助!
oracle有全文索引的(网上一搜一大堆),能快到多少不好说,试了才知道....
oracle的话,可以采用全文索引,网上自己找一下资料.
strId 就单单存取id字段就可以了。可以这样子
table2
keyName strid
北京 12
北京 45
北京 369
再在keyname,和strid建索引同时datable.id也建索引
查找的时候直接
select * from datatable,table2 where table2.keyname='xx' and table2.strid=datatable.id;
确实如此,而你那样写like貌似用不到索引,只有类似 like 'XXX%'才能用到(没记错的话)
当然你的需求也不适合用like,你不确定关键字的顺序,
你可以用instr(字段,'关键字')>0试试,这是oracle的,sql server里是charindex.
我也是新人,只知道这么多了,等高手吧.
谢谢你,但是我还有的要求就是 keyname='xx' or keyname='yy' or keyName='bb' 这些都有可能,不是一个条件,因为要分词,再匹配,
我目前做的就是 反向索引 http://zhangyu8374.javaeye.com/blog/86307 大概就是这个样子!
ORACLE中的反向索引主要是为了消除热块。
还有我不是用的 oracle的反向索引 基本是
http://zhangyu8374.javaeye.com/blog/86307 中的方式1:
xx 12
xx 52
xx 65
yy 54
yy 65
这样子阿,我觉得你用逗号隔开再解析这步是不必要的
我的意思是如果不用全文检索,又不分表,那么就只有下面这样用的上索引。OPER@tl> select * from test;AAA BBB
------------------------------------------------------------ ----------
北京多方式 1
打扫可达 2
商场四大 3
但是商场后台 4
单北京当商场的 5
人商场的北京 6
人商的的北京 7已选择7行。OPER@tl> create index ind_test on test(instr(aaa,'北京'));索引已创建。OPER@tl> create index ind_test2 on test(instr(aaa,'商场'));索引已创建。OPER@tl> exec dbms_stats.gather_table_stats('OPER','TEST',cascade=>true)PL/SQL 过程已成功完成。OPER@tl> set autot on
OPER@tl> select * from test
2 where instr(aaa,'商场')>0
3 and instr(aaa,'北京')>0;AAA BBB
------------------------------------------------------------ ----------
单北京当商场的 5
人商场的北京 6
执行计划
----------------------------------------------------------
Plan hash value: 3856466897----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 84 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID| TEST | 4 | 84 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_TEST | 5 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter(INSTR("AAA",'商场')>0)
2 - access(INSTR("AAA",'北京')>0)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
547 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processedOPER@tl>
谢谢您的帮助!我知道了!! 比如说我目前的状态(分词后在table2中建立了反向索引了,还有什么其他的优化办法没?我们领导说再在table2上索引——我不知道怎么做!)
id name
1 艾林商场(内江)
2 奥兰多购物中心(乐山)
3 长城购物中心(资阳)
4 长兴百货商场(绵阳)
5 成都百货商场都江堰店
6 成都人民商场(泸州)反向索引表 table2()
keyname strid
"内江", "1,11,"
"奥兰", "2,2,11603,2"
"多", "2,2,11571,11603,11694,11729"
"中心", "2,3,13,23,25,31,37,47,98,102"
"乐山", "2,10,15,16,20,21,220,"
"资阳", "3,14,43,155,460,758,759,8"
"长兴", "4,4,6132,6133,7804,8645,10953,25693,4"
"百货", "4,5,12,18,24,29,38,40,41,42,43,44"
………………table2 再索引??
你能用我说的那种方式建立索引以及查询吗?
我们公司数据库不是用的oracle,
只能是mysql 和 sql中的一个1
楼主怎么做的分词?我很感兴趣。像你上面的这种格式,应该把strid做成原子的:
keyname strid
内江 1
内江 11这样可以在keyname上建个索引之类的,然后查起来就快了
网络上找的一个分词组件,paoding啊这些都可以!这样可以在keyname上建个索引之类的,然后查起来就快了? (我现在的keyname上已经做了索引了)
内江 1
内江 11 是不是会带来数据检索上的性能损耗,而且,如果是这样的数据结构,我需要查找多关键字的话,就需要在 java程序中执行多条select 语句,我觉得还是保存在一起,然后取出来了。每个 ResultSet(结果集) 在判断strid中的每个id是否有相同的(取 交集)
随便说个10ms就让你去实现,10ms和2ms的要求从哪里来,有没有什么依据?
如果没有依据的话,那么你的试验结果就是最好的依据了。注意,SQL语句里面的 '%A%B%' 是和顺序有关的,这个条件搜索结果和 '%B%A%' 是不一样的。
而且 like '%A%B%' 这样的语句,很多时候根本无法使用索引,所以快不起来。你们领导说的分词,再建索引表那些东西,其实和lucene建索引时很相似,但lucene是用倒排表
如果要在数据库里面实现这些东西,还不如考虑使用lucene呢另外,你可以考虑使用数据库本身的全文索引功能,这不完全是针对大文本的。