关于sql全文检索与lucene效率比较的摘要

关于sql全文检索与lucene效率比较的摘要,以下仅为网络找到的效率意见,近期会对效率做出测试比较,再更新。

 

--------------------------------------------------------------------------------------------------------------------

 

观点一:

1.查询速度问题
         lucene在查找100W 数据的时间 控制在0.02秒左右,相反的在Sql中100W的全文检索 我想应该在10秒之后.
       2.索引速度
          两者都差不多 有可能数据库为快点.
       3.全文检索关键字分词的问题
          做过尝试 要想做好一个检索系统 分词是必不可少的.曾经试过 用户输入的关键字经过分词后产生一个SQL语句 发觉很长很长. 这样效率就很低 速度很慢慢. lucene来说 目前已经有很多标准的分词的组件 直接拿来用 .
       4.索引的利用机制
           在SQL中全文检索 不可避免的 不能100%利用到索引. like %*% 是用不到索引的。. contain  通配符等等 都无法100%利用索引,那么在这么中情况下 你SQL的索引是否有必要就值得思考.
       5.应用场景分析
           sql 100w以内的数据 还是勉强能OK .
          lucene 就不限制了.(目前 正在做的一个搜索引擎 数据量5T 将近5亿数据 时间维持在0.4秒以内  目前还在优化)
       6.分析原理
           lucene的索引机制采用的是倒叉排序,SQL 说到底还是以文件形式存放在计算机上.而且SQL 无法对TEXT 字段建立索引吧!
       建议: 在数据库记录100W的时候 可以不使用lucene使用数据库分区技术来提高速度 勉强能合格.至于说SQL 是否支持 就不 太清楚了.mysql 5.0以上是支持的 分区后速度应该能提高几倍左右.

 

 

--------------------------------------------------------------------------------------------------------------------

观点二:

 

1.Like 模糊查询
例如: select * from table where productdes like '%cad%'
它不能利用索引查询, 只能是全表扫描, 效率较低, 但查询结果准确.

2.SQL Server 2008全文检索
为了提高效率, 换用sql server的全文检索, 怎么建全文检索就此略去, 不提, 只看查询方法.
例如: select * from table where contains(ProductDesc, '*cad*')
它查询的效率很高, 中文分词没有问题, 但缺点竟然是在英文查询上, 如果想模糊查询带cad三个字母的数据, 它只能搜索出以cad为完整单词的数据, 例如: 它能查出abc cad , cad def, 或者cad, 它不能查出autocad这种字母连在一起的数据, 也就是说, sql server的全文检索的英文分词是空格.

3.Lucene全文检索
SQL server全文检索不灵了, 只能找第三方的方案了, 首当其冲的就是Lucene了, 但在.net下, Lucene却很不顺当.
NLucene是将 Lucene 从 Java 移植到 .NET 的一个 SourceForge 项目,它从 Lucene 1.2 版本转化而来, 但2002年就停止更新了.
因为 NLucene 项目到2002年就没有再推出新的版本,可Lucene 却一直在发展,于是有人把Lucene 1.3版移植到.NET就成了Lucene .NET,但是Lucene .Net发展到2.0版的时候变成了商业化的产品,脱离了开源项目, 听说现在进了孵化器已停止开发了, 但上官网http://incubator.apache.org/lucene.net/download.html上看, 还仍然在更新中似乎没有停止, 最新开源的版本是2.9.2, 发布日期是2011年5月6日, 他们还在准备2.9.4版.
受到Lucene.Net脱离开源项目的影响,有人为了继续发展开源.Net搜索引擎,于是在Lucene.Net的原有基础上继续发展该项目,但是名字改成了DotLucene以区别于Lucene.Net。但现在打开官网一看, 得, 又停止了. 看来, 只能用Lucene.Net2.0这最后一个开源版本了.
建索引, 查索引的代码如下:
        private void btnCreateIndex_Click(object sender, EventArgs e)
        {
            StringBuilder sbSQL = new StringBuilder();
            sbSQL.AppendLine(" Select ProductName, ProductDesc from Tbl_Product  ");
            dt = DataHelper.RetrieveData(sbSQL.ToString());        
            //建立索引
            IndexWriter writer = CreateIndex(dt);
        }


        public IndexWriter CreateIndex(DataTable dt)
        {
            IndexWriter writer = new IndexWriter("c:/index/", new StandardAnalyzer(), true);
            try
            {
                //建立索引字段
                foreach(DataRow dr in dt.Rows)
                {
                    Document doc=new Document();
                    doc.Add(new Field("ProductName", dr[0].ToString(), Field.Store.YES, Field.Index.TOKENIZED));
                    doc.Add(new Field("ProductDesc", dr[1].ToString(), Field.Store.YES, Field.Index.TOKENIZED));
                    writer.AddDocument(doc);                                   
                }
                writer.Optimize();
                writer.Close();
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);              
            }
            return writer;
        }

        private void Search_Click(object sender, EventArgs e)
        {
            string key = this.textBox1.Text;
            IndexSearcher search = new IndexSearcher(@"c:/index/"); //把刚才建立的索引取出来
            Term t = new Term("ProductDesc", "*" + key + "*");
            WildcardQuery query = new WildcardQuery(t);
            Hits hit = search.Search(query);
            DataTable dt = new DataTable();
            dt.Columns.Add("ProductDesc");
            for (int i = 0; i <= hit.Length() - 1; i++)
            {
                DataRow dr = dt.NewRow();
                dr[0] = hit.Doc(i).GetField("ProductDesc").StringValue();
                dt.Rows.Add(dr);
            }
            this.dataGridView1.DataSource = dt;
        }
关键是下面这两句:
Term t = new Term("ProductDesc", "*" + key + "*");
WildcardQuery query = new WildcardQuery(t);
它通过WildcardQuery(通配符查询, 包括?和*) 实现了类似like的模糊查询, 这样, 就解决了上面like查得出但慢, sqlserver full-text search虽快但查不出来的问题.
但据说lucene建(更新)索引时不能查, 查时则不能建(更新)索引, 还没细看,如果是这样, 还是有些不爽.
4.全文索引和like语句比较
全文索引的执行效率高.一般全文索引使用的是倒排索引,能够支持多关键字的索引,而LIKE只有前缀匹配时才能使用索引,否则就是全表扫描,效率当然很低
当然是全文索引效率高。但全文索引存在填充问题,需要在增加内容后进行增量填充,否则检索不到新增的内容的。可以设置调度来自动运行。
5.倒排索引 inverted index
为什么Sql server全文检索和Lucune全文检索速度快呢, 因为它和大多数搜索引擎一样, 都使用了倒排索引 inverted index

从别人那里抄了例子, 如下:
假设有3篇文章:
文章1的内容为:I was a student, i came from chengdu.
文章2的内容为:My father is a teacher, and i am a student.
文章3的内容为:Chengdu is my hometown. my father’s hometown is wuhan.
Lucene是基于关键字索引和查询的。首先取得这3篇文章的关键字,通常需要如下处理措施(在Lucene中以下措施由Analyzer类完成):
1)需要把3篇文章的内容切分成一个个单词,作为索引关键字的候选集。英文中单词与单词之间有空格,分词比较好处理,但中文字与字之间没有空隔,是连在一起的,所以中文分词处理要麻烦。
2)需要将文章中分离出来的没有实际意义的单词过滤掉。比如a、from、and,中文中的“的”、“也”、“啊”等通常无具体含义的词可以去掉。还要过滤掉标点符号。
3)单词需要统一大小写。
4)查找与当前关键字相关联的其他关键字,即统一单词不同的时态。如“came”、“coming”统一成“come”,再进行查找。
经过上面处理后,3篇文章的所有关键字为:
文章1: [am] [student] [come] [chengdu]
文章2:[my] [father] [is] [teacher] [am] [student]
文章3:[chengdu] [is] [my] [hometown] [my] [father] [hometown] [is] [wuhan]
有了关键字后,就可以建立倒排索引了。上面的对应关系是顺排的,即“文章号→关键字”,倒排处理为“关键字→文章号”。文章1、2、3经过倒排后变成如表5-1所示。
表5-1 倒排文件

 

 





i

12

am

12

student

12

come

1

chengdu

1,3

my

2,3

father

2,3

is

2,3

teacher

2

hometown

3

wuhan

3


最后推荐几个学习资料:
1.全文检索与Lucene学习
http://www.cnblogs.com/keith2011/archive/2011/09/12/2173984.html
2.Lucene:WildcardQuery

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用Lucene实现对MySQL数据表的全文检索是一种可行的方案。Lucene是一套开源的全文检索和搜寻的程式库,它提供了一个简单但强大的应用程式接口,能够实现全文索引和搜寻的功能。在Java开发环境中,Lucene是一个成熟的免费开源工具,被广泛应用于信息检索领域。 全文检索是一种针对非结构化数据的检索方法,对于像磁盘上的文件、网站资源等非结构化数据,无法使用SQL语句进行查询,因此需要使用全文检索法。全文检索法将非结构化数据中的一部分信息提取出来进行组织,形成索引,然后根据索引快速定位到要查找的信息。Lucene可以实现全文检索的功能,它是Apache软件基金会支持和提供的工具包。 使用Lucene实现全文检索的流程如下: 1. 创建索引:首先获取要进行检索的文档,可以是磁盘文件或网站资源等,然后构建文档对象,包括多个域,如文件名称、文件路径、文件大小、文件内容等。接下来对文档进行分词,将分词结果创建为索引并添加到索引库中。 2. 索引搜索:创建查询对象,执行查询并渲染结果。在倒排索引词典表中查找对应搜索词的索引,然后找到索引所链接的文档。例如,搜索语法为"fileName:lucene"表示搜索文件名中包含Lucene文档。 要使用Lucene实现全文检索,首先需要下载和配置Lucene。你可以从官方网站或其他可信的资源下载Lucene的安装包,并按照相应的指南进行配置。然后,你可以使用Lucene提供的API来实现全文检索功能,根据具体需求进行代码编写和调用。 总之,Lucene是一种强大的全文检索工具,可以帮助你在MySQL数据表中实现全文检索功能。你可以通过学习和使用Lucene的API来了解更多关于Lucene的功能和用法,并根据具体需求进行相应的实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【springboot微服务】Lucence实现Mysql全文检索](https://blog.csdn.net/zhangcongyi420/article/details/129940816)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [【Lucene&Solr】Lucene实现全文检索](https://blog.csdn.net/qq_43705275/article/details/107229299)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值