`
chudu
  • 浏览: 6501 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

我做的lucene性能测试,以及对其搜索速度的疑问,望高手指点

阅读更多

最近开始学习lucene,在网上看了不少性能测试,很多都是相互copy,都说100万条数据搜索速度在0.X秒级别。我觉得速度还可以,应该能应用在我现在所做的项目中,处于谨慎,我自己也做了下性能测试,却达不到网上的搜索速度,觉得疑惑,特贴出代码和环境信息。

     1,我的速度达不到0.x,是我的代码那里有问题吗?

     2,我搜索时,为什么建好索引后的第一次搜索往往能达到毫秒级别,而以后都是秒级别的?

下面是测试环境信息:

     测试CPU P8600 ,内存4G,源文件总大小1.18G,文件个数6938。

     不分词但存储的字段:文件名,文件路径,时间。分词但不存储:文件内容。采用Lucene3.0.0,用的分词器:IKAnalyzer3.2

测试结果:

megerFactory MaxBufferedDocs 分词器 索引文件大小(M) 索引时间(ms) 搜索时间(ms) 搜索数量
默认10 默认10 IKAnalyzer3.2 773 1204218 641 1266 1235 1266 1250 100
100 默认10 IKAnalyzer3.2 782 1142031 657 1344 1328 1343 1328 100
1000 默认10 IKAnalyzer3.2 782 1143469 672 1359 1313 1344 1344 100
默认10 100 IKAnalyzer3.2 772 1074516 609 1281 1282 1266 1282 100
默认10 1000 IKAnalyzer3.2 773 1124516 593 1297 1281 1297 1281 100


下面是代码:

package org.lucene.mytest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
public class LuceneTest {
    static File dataDir = new File("D:\\study\\lucene\\data");
    static File indexDir = new File("D:\\study\\lucene\\index");
    static String content = "content";
    static String name = "fileName";
    static String indexDate = "indexDate";
    static String filePath = "filePath";
    public static void main(String[] args) {
         long startTime = System.currentTimeMillis();
         try {
         //索引,在搜索测试时注释。
         indexDocs(new SimpleFSDirectory(indexDir));
         } catch (IOException e) {
         e.printStackTrace();
         }
         long endTime = System.currentTimeMillis();
         System.out.println("index:-----" + (endTime - startTime));
        //搜索
        long startTime1 = System.currentTimeMillis();
        testSearch();
        long endTime1 = System.currentTimeMillis();
        System.out.println("search:----" + (endTime1 - startTime1));
    }
    public static void testSearch() {
        try {
            Directory indexFSDir = new SimpleFSDirectory(indexDir);
            IndexReader indexReader = IndexReader.open(indexFSDir, true);
            Searcher searcher = new IndexSearcher(indexReader);
            QueryParser parser = new QueryParser(Version.LUCENE_CURRENT,
                    content, new IKAnalyzer());
            Query query = parser.parse("经受住了大战和时间的洗礼");
            TopDocs tdoc = searcher.search(query, 100);
            for (ScoreDoc scoreDoc : tdoc.scoreDocs) {
                Document doc = searcher.doc(scoreDoc.doc);
            }
            searcher.close();
            indexFSDir.close();
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    public static void indexDocs(Directory indexDir) {
        if (indexDir == null || dataDir == null)
            return;
        IndexWriter iw = null;
        try {
            iw = new IndexWriter(indexDir, new IKAnalyzer(), true,
                    IndexWriter.MaxFieldLength.UNLIMITED);
            for (File f : dataDir.listFiles()) {
                Document doc = readDocument(f);
                if (doc != null)
                    iw.addDocument(doc);
            }
            iw.close();
            indexDir.close();
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (LockObtainFailedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static Document readDocument(File file) {
        Document doc = new Document();
        Field c;
        try {
            c = new Field(content, new BufferedReader(new InputStreamReader(
                    new FileInputStream(file), "GBK")));
            doc.add(c);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Field n = new Field(name, file.getName(), Field.Store.YES,
                Field.Index.NOT_ANALYZED);
        doc.add(n);
        Field p = new Field(filePath, file.getAbsolutePath(), Field.Store.YES,
                Field.Index.NOT_ANALYZED);
        doc.add(p);
        Field id = new Field(indexDate, new Date().toString(), Field.Store.YES,
                Field.Index.NOT_ANALYZED);
        doc.add(id);
        return doc;
    }
}

 

分享到:
评论
17 楼 srdrm 2010-08-04  
应该还是没有使用好lucene,不会这么慢的。
16 楼 harbey 2010-07-27  
个人感觉不要去太追求速度了,lucene是一个很成熟的解决方案,给我们应用开发提供了很多方便。可以用jprofiler去跑一下程序,看看性能参数。搜索的话可以用缓存加以优化(例如enhcache或memcached等)提高查询速度等。
15 楼 dukai1008 2010-07-27  
我也想用在自己的项目中,测试过,速度很快的,上G的还没测试过,晚上回去试试,明天再跟贴!
14 楼 lishuaibt 2010-07-27  
难道是IO缓存? 操作系统的Cache。。
13 楼 chudu 2010-07-26  
yangfuchao418 写道
不清楚楼主的测试。我把你的代码拷贝下来再公司里的机器测试。先把那两个文件夹建立好。然后按你说的运行。相差不过几十毫秒

?很神奇呀。
12 楼 yangfuchao418 2010-07-26  
不清楚楼主的测试。我把你的代码拷贝下来再公司里的机器测试。先把那两个文件夹建立好。然后按你说的运行。相差不过几十毫秒
11 楼 chudu 2010-07-26  
lishuaibt 写道
# TopDocs tdoc = searcher.search(query, 100); 
#             for (ScoreDoc scoreDoc : tdoc.scoreDocs) { 
#                 Document doc = searcher.doc(scoreDoc.doc); 
#             } 
#             searcher.close(); 
#             indexFSDir.close();

IndexReader的open操作是比较耗时的操作,如果没有索引的变更,是没有必要这么频繁的close()后重新open的,重用IndexReader对象,会减少很所不必要的重复加载,比如SegementInfo的加载等操作。。。。


我不是用的for,从代码可看出。

当每次索引后立即执行搜索方法,则搜索时间短。而如果将索引方法注释在执行main时,搜索方法用时长。你说indexReader每次打开操作比较耗时,但我每次都是同样的打开关闭,时间应在相同的一个范围内,而不会相差这么远啦。

为什么第一次执行速度明显比后面的快很多呢?我执行了十几次都是这样的。
10 楼 forchenyun 2010-07-26  
关注。。。。。。
9 楼 ccx007 2010-07-26  
indexReader 和IndexSearcher都设成全局的,不要每查询一次就关闭,再打开索引的是很耗时的,实际应用中也不会每次search都关闭searcher
8 楼 lzj0470 2010-07-26  
没有那么慢的,我二百多万个文本文件,大小是10K,都很快。一般是在1秒左右。
7 楼 lishuaibt 2010-07-26  
# TopDocs tdoc = searcher.search(query, 100); 
#             for (ScoreDoc scoreDoc : tdoc.scoreDocs) { 
#                 Document doc = searcher.doc(scoreDoc.doc); 
#             } 
#             searcher.close(); 
#             indexFSDir.close();

IndexReader的open操作是比较耗时的操作,如果没有索引的变更,是没有必要这么频繁的close()后重新open的,重用IndexReader对象,会减少很所不必要的重复加载,比如SegementInfo的加载等操作。。。。
6 楼 sw861203 2010-07-26  
我的意思是起项目测试,不要放在junit里测。
5 楼 sw861203 2010-07-26  
你是不是放在junit里测试的。正常的话第一次很慢,后面应该很快的。
4 楼 anhaoy 2010-07-26  
IndexReader打开之后不关闭,持续使用的话,搜索速度是很快的!
Lucene的索引是有缓存的,基于IndexReader的缓存。G级的索引文件、百万条以上的数据,查找(分页,每页数十条记录)花费时间应该是几十毫秒,更低也是有可能的。
3 楼 chudu 2010-07-25  
chudu 写道
kafka0102 写道
以你上G的数据建索引需要个20分钟是有些慢,但也是可想像范围内。那么多的数据显然不可能秒级别搞定的,连分词的时间都不够用。至于查询,不知道你连续的测试是在testSearch里加了for循环测的吗?通常在一次查询过后后续的会更快的,但如果你没有特别指定启动参数,也有可能是内存不够导致频繁的gc,可打印gc信息观察下。

恩,还有比较疑惑:
第一次的搜索时间为什么明显快些。
#   long startTime = System.currentTimeMillis();  
#          try {  
#          //索引,在搜索测试时注释。  
#          indexDocs(new SimpleFSDirectory(indexDir));  
#          } catch (IOException e) {  
#          e.printStackTrace();  
#          }  
#          long endTime = System.currentTimeMillis();  
#          System.out.println("index:-----" + (endTime - startTime));  
#         //搜索  
#         long startTime1 = System.currentTimeMillis();  
#         testSearch();  
#         long endTime1 = System.currentTimeMillis();  
#         System.out.println("search:----" + (endTime1 - startTime1));  

第一次是执行完索引后直接执行的搜索,第二次及以后都是将索引注释后去执行的。不是for循环执行testSearch,而是重新执行main.

2 楼 chudu 2010-07-25  
kafka0102 写道
以你上G的数据建索引需要个20分钟是有些慢,但也是可想像范围内。那么多的数据显然不可能秒级别搞定的,连分词的时间都不够用。至于查询,不知道你连续的测试是在testSearch里加了for循环测的吗?通常在一次查询过后后续的会更快的,但如果你没有特别指定启动参数,也有可能是内存不够导致频繁的gc,可打印gc信息观察下。

恩,还有比较疑惑:
第一次的搜索时间为什么明显快些。
#   long startTime = System.currentTimeMillis();  
#          try {  
#          //索引,在搜索测试时注释。  
#          indexDocs(new SimpleFSDirectory(indexDir));  
#          } catch (IOException e) {  
#          e.printStackTrace();  
#          }  
#          long endTime = System.currentTimeMillis();  
#          System.out.println("index:-----" + (endTime - startTime));  
#         //搜索  
#         long startTime1 = System.currentTimeMillis();  
#         testSearch();  
#         long endTime1 = System.currentTimeMillis();  
#         System.out.println("search:----" + (endTime1 - startTime1));  

第一次是执行完索引后直接执行的搜索,第二次及以后都是将索引注释后去执行的。
1 楼 kafka0102 2010-07-25  
以你上G的数据建索引需要个20分钟是有些慢,但也是可想像范围内。那么多的数据显然不可能秒级别搞定的,连分词的时间都不够用。至于查询,不知道你连续的测试是在testSearch里加了for循环测的吗?通常在一次查询过后后续的会更快的,但如果你没有特别指定启动参数,也有可能是内存不够导致频繁的gc,可打印gc信息观察下。

相关推荐

    lucene的封装和性能优化

    然而,为了更好地适应实际项目需求,通常需要对其进行封装,以便于管理和提升性能。本文将深入探讨Lucene的封装方法以及如何进行性能优化。 ### 1. Lucene的基础概念 Lucene的核心功能包括索引和搜索。索引是将...

    lucene分词测试代码

    用java写的图形分词测试的小东西,用的分词器是: 来自“猎图网 www.richmap.cn”基于IKAnalyzer分词算法的准商业化Lucene中文分词器,其使用“正向全切分算法”,42万汉字字符/每秒的处理能力(IBM ThinkPad 酷睿I...

    Lucene测试程序3.5

    在这个测试程序中,开发者可能使用了Lucene自带的标准分词器(StandardAnalyzer),它对英文文本进行了诸如词干提取和停用词过滤等处理,提高了搜索精度。 标准分词器(StandardAnalyzer)是Lucene提供的一种通用...

    lucene-性能实验

    NULL 博文链接:https://sunfish.iteye.com/blog/1415655

    基于Java的全文搜索引擎性能对比与分析:Lucene、FTServer全面评测与搜索速度测试

    本项目深入探讨了Java环境下全文搜索引擎的性能对比,具体针对Lucene和FTServer两大搜索引擎进行了全面的评测。项目包含24个文件,涵盖10个Java源文件、5个JAR包文件、3个XML配置文件、2个属性文件等,旨在通过详细...

    lucene 2.0 api以及lucene 3.0 api

    总的来说,从 Lucene 2.0 进化到 3.0,主要变化在于性能提升、查询功能增强以及对更多场景的支持,这些改进使得 Lucene 成为了更加成熟和全面的全文搜索解决方案。学习并掌握这两个版本的 API,对于从事相关开发工作...

    lucene3.6 搜索例子

    在本篇文章中,我们将深入探讨Lucene 3.6版本中的搜索功能,通过实例解析其核心概念和操作流程。 一、Lucene概述 Lucene的出现,使得开发人员能够轻松地在他们的应用中添加高级搜索功能。作为一个高性能的信息检索...

    Lucene 4.7 测试案例

    1. **性能提升**:通过优化内部数据结构和算法,Lucene 4.7显著提高了索引和查询的速度。例如,对Term查询的优化使得频繁的短语查询更为快速。 2. **内存管理优化**:内存使用量的减少意味着在处理大量数据时,系统...

    lucene做的桌面搜索

    该程序旨在提供快速、准确的本地文件搜索服务,尽管目前仍存在一些待优化之处,如界面运行速度较慢,但其核心功能已经初具雏形。 Lucene,由Apache软件基金会开发,是一款开源全文检索库,广泛应用于各种搜索引擎的...

    lucene对数据库操作

    这可能涉及SQL查询来获取所需字段,然后进行预处理,如分词、去除停用词和标点符号,以及词干提取等,以优化搜索性能。 2. **创建Lucene Document**:每个数据库记录对应一个Lucene Document对象,其中包含字段...

    lucene站内搜索

    Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,被广泛应用于各种搜索引擎和站内搜索解决方案中。它提供了丰富的文本分析、索引和搜索功能,使得开发者能够轻松地在自己的应用程序中实现复杂的全文检索...

    Lucene 2.0.0下载安装及简单测试

    Lucene是一款高性能、全功能的文本搜索引擎库,由Java编写,旨在为应用提供快速、高效的全文检索能力。它不仅仅是一个简单的索引和搜索工具,还提供了丰富的查询语言、分词器和其他高级功能。对于希望在其应用程序中...

    开发自己的搜索引擎 lucene + heritrix

    Lucene 的主要优势在于其强大的搜索能力、高效率、灵活性以及易于集成等特点。它支持全文索引和搜索,并能够处理大量数据。Lucene 能够实现包括数据索引、查询分析、排序和高亮显示等搜索功能。它还能够进行复杂的...

    lucene的简单介绍以及使用

    你可以利用 Lucene 对站内新闻、数据库表字段、甚至创建自定义搜索引擎进行索引和搜索。通过 Lucene,你可以实现对大量文本数据的高效检索,提升用户体验。 **是否选择 Lucene** 决定是否使用 Lucene,通常需要考虑...

    lucene搜索引擎项目

    《深入理解Lucene搜索引擎项目》 Lucene是一个高性能、全文本搜索库,它为开发者提供了在Java应用程序中实现全文检索的工具集。这个名为“lucene搜索引擎项目”的资源,旨在帮助用户更好地理解和应用Lucene来构建...

    springmvc集成lucene全文搜索

    集成Spring MVC和Lucene能为Web应用带来高效的全文搜索功能,提高用户查找信息的速度和准确性。然而,实际应用中需要考虑的因素很多,如并发控制、索引重建策略、性能优化等,因此在开发过程中需要不断调整和优化,...

    Java搜索引擎 Lucene

    Java搜索引擎Lucene是一款开源的全文检索库,由Apache软件基金会开发并维护,它为Java开发者提供了强大的文本搜索功能。Lucene的核心目标是让开发者能够快速地在应用中集成高级的搜索功能,使得用户可以轻松地查找和...

    lucene 高级搜索项目

    在这个“Lucene 高级搜索项目”中,我们将深入探讨如何利用Lucene实现附件搜索、附件内容搜索以及全文搜索等高级功能。 **1. Lucene 搜索引擎基础** Lucene 的核心工作流程包括索引创建和搜索两部分。首先,我们...

    lucene 实现类似百度搜索

    **Lucene 搜索引擎实现详解** Lucene 是一个开源全文搜索引擎库,由 Apache 软件基金会维护。...无论是在网站、应用还是大数据环境中,Lucene 都能以其高效的全文检索能力,为用户提供快速、准确的搜索结果。

Global site tag (gtag.js) - Google Analytics