博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucene检索与关键字Like 性能对比
阅读量:5953 次
发布时间:2019-06-19

本文共 3688 字,大约阅读时间需要 12 分钟。

     日常开发中,相信大家经常会用like去匹配一些数据,同时我们也知道,like往往会导致全表扫描,当数据量越来越大的时候,我们会纠结于

数据库的龟速查找,此时我们必须另寻蹊跷,这时lucene就可以大显身手了。

     首先我们做一个demo,向数据库中插入10w条数据,总共778M。

 

接下来,我们搜索下新闻内容中包含“流行”的记录。

 

 

mmd,检索一下要78s,是谁都要砸了面前的破机子。

下面我们来看看lucene的效果怎么样。下载地址:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Lucene.Net.Index; 6 using Lucene.Net.Store; 7 using Lucene.Net.Analysis.Standard; 8 using Lucene.Net.Documents; 9 using System.Data;10 using System.Diagnostics;11 using Lucene.Net.Search;12 13 using Lucene.Net.QueryParsers;14 15 namespace First16 {17     class Program18     {19         static string path = @"D:\Sample";20 21         static void Main(string[] args)22         {23             //创建索引24             CreateIndex();25 26             var watch = Stopwatch.StartNew();27 28             //搜索29             IndexSearcher search = new IndexSearcher(path);30 31             //查询表达式32             QueryParser query = new QueryParser(string.Empty, new StandardAnalyzer());33 34             //query.parse:注入查询条件35             var hits = search.Search(query.Parse("Content:流行"));36 37             for (int i = 0; i < hits.Length(); i++)38             {39                 Console.WriteLine("当前内容:{0}", hits.Doc(i).Get("Content").Substring(0, 20) + "...");40             }41 42             watch.Stop();43 44             Console.WriteLine("搜索耗费时间:{0}", watch.ElapsedMilliseconds);45         }46 47         static void CreateIndex()48         {49             //创建索引库目录50             var directory = FSDirectory.GetDirectory(path, true);51 52             //创建一个索引,采用StandardAnalyzer对句子进行分词53             IndexWriter indexWriter = new IndexWriter(directory, new StandardAnalyzer());54 55             var reader = DbHelperSQL.ExecuteReader("select * from News");56 57             while (reader.Read())58             {59                 //域的集合:文档,类似于表的行60                 Document doc = new Document();61 62                 //要索引的字段63                 doc.Add(new Field("ID", reader["ID"].ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));64                 doc.Add(new Field("Title", reader["Title"].ToString(), Field.Store.NO, Field.Index.ANALYZED));65                 doc.Add(new Field("Content", reader["Content"].ToString(), Field.Store.YES, Field.Index.ANALYZED));66 67                 indexWriter.AddDocument(doc);68             }69 70             reader.Close();71 72             //对索引文件进行优化73             indexWriter.Optimize();74 75             indexWriter.Close();76         }77     }78 }

  

 

我靠,448ms,顿时78s黯然失色,当然这个时间是不包含"创建索引“的时间,从时间复杂度上来说,这种预加载索引算是常量。

 

作为入门,简单的介绍下lucene的实现过程,首先lucene主要分成两步:"索引"和"搜索"。

 

一:索引:

相信大家对索引还是比较熟悉的,lucene能够将我们内容切分成很多词,然后将词作为key,建立“倒排索引”,然后放到索引库中,在上面

的例子中,我们看到了索引过程中使用到了IndexWriter,FSDirectory,StandardAnalyzer,Document和Field这些类,下面简要分析下。

 

1:IndexWriter

    我们看到该类有一个AddDocument方法,所以我们认为该类实现了索引的写入操作。

 

2:FSDirectory

    这个就更简单了,提供了索引库的存放位置,比如我们这里的D:\Sample,或许有人问,能不能存放在内存中,在强大的lucene面前当然

可以做到,lucene中的RAMDirectory就可以实现,当然我们的内存足够大的话,还是可以用内存承载索引库,进而提高搜索的效率。

 

3:StandardAnalyzer

   这个算是索引过程中最最关键的一步,也是我们使用lucene非常慎重考虑的东西,之所以我们能搜索秒杀,关键在于我们如何将输入的内容

进行何种形式的切分,当然不同的切分形式诞生了不同的分析器,StandardAnalyzer就是一个按照单字分词的一种分析器,详细的介绍后续文

章分享。

 

4:Document

 在上面的例子可以看到,他是承载field的集合,然后添加到IndexWriter中,有点类似表中的行的概念。

 

5: Field

提供了对要分析的字段进行何种处理,以KV形式呈现。

①:Field.Store.YES, Field.Index.NOT_ANALYZED   表示对索引字段采取:原样保存并且不被StandardAnalyzer进行切分。

②: Field.Store.NO, Field.Index.ANALYZED             不保存但是要被StandardAnalyzer切分。

 

二:搜索

这个比较容易,根据我们输入的词lucene能够在索引库中快速定位到我们要找的词,同样我们可以看到IndexSearcher,QueryParser,Hits。

 

1:IndexSearcher

   这个我们可以理解成以只读的形式打开由IndexWriter创建的索引库,search给QueryParser提供了查询的桥梁。

 

2:QueryParser

   这玩意提供了一个parse方法能够将我们要查找的词转化为lucene能够理解了查询表达式。

 

3:Hits

   这个就是获取匹配结果的一个指针,优点类似C#中的延迟加载,目的都是一样,提高性能。  

转载地址:http://graxx.baihongyu.com/

你可能感兴趣的文章
vc中运行外部程序的方法
查看>>
[51单片机] SPI nRF24L01无线 [可以放在2个单片机里实现通信]
查看>>
面试题:在O(1)空间复杂度范围内对一个数组中前后连段有序数组进行归并排序...
查看>>
用ajax技术实现无闪烁定时刷新页面
查看>>
子进程清理
查看>>
HDU1022 Train Problem I
查看>>
微软已停止对Vista RTM(SP0)的服务支持
查看>>
Spring依赖检查
查看>>
第 72 章 FAQ
查看>>
Activity 切换 动画
查看>>
[LeetCode] Sum of Left Leaves 左子叶之和
查看>>
[LeetCode] Find Median from Data Stream
查看>>
3.6. Pure-FTPd + LDAP + MySQL + PGSQL + Virtual-Users + Quota
查看>>
50.9. 触发器(Trigger)
查看>>
9.3. where 优化
查看>>
《基于MFC的OpenGL编程》Part 18 Reading objects from the OBJ File Format
查看>>
Spring 文件上传功能
查看>>
RAC静默安装与DG搭建
查看>>
windows 下mysql的安装于使用(启动、关闭)
查看>>
Android 中文 API (28) —— CheckedTextView
查看>>