Lucene 3.6.1 先排序后分页如何优化性能(见源码)
public ArrayList queryIndexList(String id1, String id2, String id3, int curpage, int pageSize) {
ArrayList list = new ArrayList();
try {
if (curpage <= 0) {
curpage = 1;
}
if (pageSize <= 0) {
pageSize = 20;
}
this.pageSize = pageSize; //每页记录数
this.currentPage = curpage; //当前页
int start = (curpage - 1) * pageSize;
BooleanQuery bQuery = new BooleanQuery();
if (!"".equals(id1)) {
WildcardQuery w1 = new WildcardQuery(new Term("idml", id1 + "*"));
bQuery.add(w1, BooleanClause.Occur.SHOULD);
}
if (!"".equals(id2)) {
WildcardQuery w1 = new WildcardQuery(new Term("idml", id2 + "*"));
bQuery.add(w1, BooleanClause.Occur.SHOULD);
}
if (!"".equals(id3)) {
WildcardQuery w1 = new WildcardQuery(new Term("idml", id3 + "*"));
bQuery.add(w1, BooleanClause.Occur.SHOULD);
}
int hm = start + pageSize;
TopScoreDocCollector res = TopScoreDocCollector.create(pageSize, false);//TopScoreDocCollector.create(hm, false); 原分页方法
searcher.search(bQuery, res); //第一次查询取出总条数
this.rowCount = res.getTotalHits();
this.pages = (rowCount - 1) / pageSize + 1; //计算总页数
if(rowCount>0){
TopDocs tds = searcher.search(bQuery, rowCount, sort);//第二次查询取全部排序结果 res.topDocs(start, pageSize) 原分页方法
ScoreDoc[] sd = tds.scoreDocs;
int i = 0;
for (ScoreDoc scoreDoc : sd) {
i++;
if (i < start) {
continue;//分页判断
}
if (i > hm) {
break;//分页判断
}
Document doc = searcher.doc(scoreDoc.doc);
list.add(createObj(doc));//封装对象
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
。
9283 页,20条/页,共计185646条,平均消耗458毫秒。(而且并发的时候耗时会成倍增加,显然上面的代码不太可取)
影响性能的主要是:1)查询了两次,2)排序取所有结果,后用i来判断取分页值。
。。-----------------------
想了个法子,就是在创建索引库的时候进行排序,可不知道lucene通配符查询出来的顺序是否是创建的时候的顺序(分词查询的时候是根据相似度),这个方法待验证,另外这样仅支持单字段排序。
对于多字段分别排序,莫非要创建不同的索引库?都是要验证的,明天有结果再告诉大家。
。。-----------------------
果然可行哈哈~~~~问题解决了~~
共 10777 页,20条/页,共计215524条
第一页平均24ms,最后一页平均255ms。
最终解决方案发在自己的网站了:http://www.wizzer.cn/?p=2299
万死的路人
12 years ago
Answers
请使用3.5之后新引入的api searchAfter
http://lucene.apache.org/core/old_ver... , org.apache.lucene.search.Query, int)
忧郁D上帝
answered 12 years ago