知识点
相关文章
更多最近更新
更多一次针对批量查询处理的优化
2019-03-27 01:05|来源: 网路
客户调用批量查询接口对Solr核进行查询时觉得查询响应时间有些慢,接口的内部实现目前是顺序执行每个查询,再把结果汇总起来返回给调用方。因此,考虑引入线程池对查询接口的内部实现进行重构优化。
先声明一个大小可随之增长的线程池,
private ExecutorService executor = Executors.newCachedThreadPool();
//
查询请求处理线程池
然后是主线程方法的代码:
public List<Map<String, String>> queryEntityList(String entityCode, List<Long> idList) throws ServiceException {
List<Map<String, String>> finalResult =
null;
if (idList == null || idList.size() == 0 || StringUtil.isBlank(entityCode)) { // 参数合法性校验
return finalResult;
}
finalResult = new ArrayList<Map<String, String>>();
List<Future<Map<String, String>>> futureList = new ArrayList<Future<Map<String, String>>>();
int threadNum = idList.size(); // 查询子线程数目
for ( int i = 0; i < threadNum; i++) {
Long itemId = idList.get(i);
Future<Map<String, String>> future = executor.submit( new QueryCallable (entityCode, itemId));
futureList.add(future);
}
for(Future<Map<String, String>> future : futureList) {
Map<String, String> threadResult = null;
try {
threadResult = future.get();
} catch (Exception e) {
threadResult = null;
}
if ( null != threadResult && threadResult.size() > 0) { // 结果集不为空
finalResult.add(threadResult);
}
}
return finalResult;
}
if (idList == null || idList.size() == 0 || StringUtil.isBlank(entityCode)) { // 参数合法性校验
return finalResult;
}
finalResult = new ArrayList<Map<String, String>>();
List<Future<Map<String, String>>> futureList = new ArrayList<Future<Map<String, String>>>();
int threadNum = idList.size(); // 查询子线程数目
for ( int i = 0; i < threadNum; i++) {
Long itemId = idList.get(i);
Future<Map<String, String>> future = executor.submit( new QueryCallable (entityCode, itemId));
futureList.add(future);
}
for(Future<Map<String, String>> future : futureList) {
Map<String, String> threadResult = null;
try {
threadResult = future.get();
} catch (Exception e) {
threadResult = null;
}
if ( null != threadResult && threadResult.size() > 0) { // 结果集不为空
finalResult.add(threadResult);
}
}
return finalResult;
}
最后是具体负责处理每个查询请求的
Callable
public
class QueryCallable
implements Callable<Map<String, String>> {
private String entityCode = "";
private Long itemId = 0L;
public GetEntityListCallable(String entityCode, Long itemId) {
this. entityCode = entityCode;
this.itemId = itemId;
}
public Map<String, String> call() throws Exception {
Map<String, String> entityMap = null;
try {
entityMap = QueryServiceImpl. this.getEntity(entityCode, itemId); // 先去hbase查基本信息
} catch (Exception e) {
entityMap = null;
}
return entityMap;
}
}
private String entityCode = "";
private Long itemId = 0L;
public GetEntityListCallable(String entityCode, Long itemId) {
this. entityCode = entityCode;
this.itemId = itemId;
}
public Map<String, String> call() throws Exception {
Map<String, String> entityMap = null;
try {
entityMap = QueryServiceImpl. this.getEntity(entityCode, itemId); // 先去hbase查基本信息
} catch (Exception e) {
entityMap = null;
}
return entityMap;
}
}
通过线程池的使用,可以减少创建,销毁进程所带来的系统开销,而且线程池中的工作线程可以重复使用,极大地利用现有系统资源,增加了系统吞吐量。
另外,今天也尝试了另一种合并Solr索引的方法,直接通过底层的Lucene的API进行,而不是提交Http请求,具体方法如下:
java -cp lucene-core-3.4.0.jar:lucene-misc-3.4.0.jar org/apache/lucene/misc/IndexMergeTool ./newindex ./app1/solr/data/index ./app2/solr/data/index
转自:http://www.cnblogs.com/phinecos/archive/2011/12/29/2306775
相关问答
更多-
mysql分表分库后如何进行批量查询[2022-03-15]
启几个线程并行来查,最后把结果集合并。 -
MySQL查询优化[2022-07-13]
select product_id, sum(stock_amount) as stock_amount, sum(stock_branch) as stock_branch from stock_details where product_id in(很多,但是一般不会超过1000) group by product_id 我不是很建议用 where product_id in(很多,但是一般不会超过1000) 这种的方式,这样速度会比较慢,如果考虑到优化一般都会用 where (表A.Product_I ... -
mysql中怎样对大批量级的数据查询进行优化[2021-10-06]
在我们使用MySQL数据库时,比较常用也是查询,包括基本查询,关联查询,条件查询等等,对于同一个操作,SQL语句的实现有很多种写法,但是不同的写法查询的性能可能会有很大的差异。这里主要介绍下select查询优化的要点。 1. 使用慢查询日志去发现慢查询。 2. 使用执行计划去判断查询是否正常运行。 3. 总是去测试你的查询看看是否他们运行在最佳状态下 –久而久之性能总会变化。 4. 避免在整个表上使用count(*),它可能锁住整张表。 5. 使查询保持一致以便后续相似的查询可以使用查询缓存。 6. 在适当 ... -
oracle 查询性能优化问题[2022-06-05]
像你说的,sql没有什么优化的可能了。 只能从数据库技术上面来优化,使用并行、提升io吞吐量、启用压缩、使用分区将表分片存放在不同硬盘上(如果没有使用raid的话)。 有些可疑,你可以进一步判断一下,是数据库这边查询比较慢,还是应用程序层处理起来比较慢。 -
mysql 处理 多条件 大批量数据 查询[2023-05-06]
不知道你的关联方式 再一个,10W多不算太多 关联的相关字段建立相应的索引 where条件的字段也建立相应的索引 其实也就这样 主要是看你那语句怎么写,才能确定建立什么样的索引 -
php 中同时批量执行SQL查询[2023-06-24]
那就一条一条的写不就行了啊,一条一条的执行呗 -
如何优化以下查询(How to optimize the following query)[2022-01-10]
使用OUTER APPLY SELECT fn.id, oa.rid, oa.gid FROM finding fn OUTER apply (SELECT TOP 1 s.rid, f.gid FROM find f JOIN status s ... -
好吧,不能解决这个问题,但是在石英作业中实现它,使其并发,并部署5个vms并在一天内完成该过程。 蛮力。 Well, can´t get fixed this, but implemented it in a quartz job,made it concurrent, and deployed 5 vms and get the process done in a day. Brute force.
-
DELETE FROM t1 USING t1 JOIN t2 ON t1.key = t2.key LIMIT 1000; 并重复,直到没有剩余,这允许长时间不阻止表。 UPD:但是如果你需要加入同一个表,这个解决方案将不起作用。 UPD2:我忽略了NOT ,这是更正的查询: DELETE FROM t1 USING t1 LEFT JOIN t2 ON t1.key = t2.key WHERE t2.key IS NULL LIMIT 1000; 我应该注意,这是子查询以与JOIN相同的速度执行的 ...
-
因此,经过多次改进后,我们已经改变了我们的方法,以实现我们所需的吞吐量。 事实证明,我们只关注它们在那里的100,000个记录/秒,并且它们用于更新连续滚动的聚合和实时值集。 我们使用大量工作线程将100,000行批量插入到临时堆表中(因此使用4个工作线程,每个线程处理大约25,000行),然后将聚簇索引应用于临时表。 然后,我们将临时表中的数据直接合并到实时和聚合表中,并删除临时表。 这里我们使用ROWLOCK提示强制SQL采用ROWLOCK而不是TABLOCK或PAGLOCK,这会导致工作线程之间的争用 ...