批量更新:

PreparedStatement并不能减少sql的执行数目. 参数传入多少次,就会执行多少条sql.

在一个事务中,由于Statement与PrestatedStatement都使用的同一个连接. Statement不会再象过去每次都去获取连接. 这种情况下,反而可以利用Statement优化PreparedStatement. 减少sql的执行条数. 但是每条sql会编译,获得执行计划.




示例1:质量度更新:

比如关键词在审核的过程中先去查询A表,得到该词的历史质量度, 如果有,就更新B表中的质量度值.

  public void checkQuality() {// 先取得词的历史质量度Map<String, Long> qhmap = getQualityWithAccountidAndKey(needCheckQualityKeys, accountid);// QualityHistory表中能根据groupid-key查到历史质量度.则需要更新keyspend的值.否则什么都不做.if (qhmap != null && qhmap.size() > 0) {List<KeySpend> kslist = new ArrayList<KeySpend>();for (CpcKeyDTO key : needCheckQualityKeys) {if (qhmap.get(key.getKey()) != null) {KeySpend keyspend = new KeySpend();keyspend.setCpcid(key.getCpcid());keyspend.setQuality(qhmap.get(key.getKey()));kslist.add(keyspend);}}//会在server端执行kslist.size()条sql.batchProcessKeySpend(kslist);}}

调优后的方法:

     if (qhmap != null && qhmap.size() > 0) {HashMap<Long, ArrayList<Long>> keySpendMap = new HashMap<Long, ArrayList<Long>>();//质量度有5个值, 所以每个值对应一条sql. 将来只需要5条sqlfor (CpcKeyDTO key : needCheckQualityKeys) {if (qhmap.get(key.getKey()) != null) {Long degree = qhmap.get(key.getKey());                    ArrayList<Long> list = keySpendMap.get(degree);if(list == null){list = new ArrayList<Long>();keySpendMap.put(degree, list);}list.add(key.getCpcid());                           }}//使用IN进行优化。for(Long degree : keySpendMap.keySet()){auditPersistentService.batchProcessKeySpend(degree, keySpendMap.get(degree));}         }

上面调优之后,由以前的kslist条sql变成了现在的5条sql,但是这5条sql都会重新编译.

经测试:10个Key感觉差别不是特别明显. 都在16ms. 结论待定.


示例2: 在广告系统中配对的批量插入与批量更新的一个优化示例:

批量广告插入最初使用的是merge into.但是即使使用的PreparedStatement的sql,仍然要执行25W次.

比如应用程序中形成的了一个配对的集合,包含了25W个元素.通过jdbcTemplate的batchUpdate批量插入这些元素,并且还需要判重,使用的sql如下:

/* Formatted on 2011-8-2 18:54:00 (QP5 v5.114.809.3010) */
MERGE INTO CPC.CPCPARTNERAUDIT cpa
USING (SELECT ? AS OPID,? AS ACCOUNTID,? AS GROUPID,? AS IDEAID,? AS KEYID,? AS CHECKSTATUS,? AS CREATEDATE,? AS REFUSEREASON, ? AS ADMINUSERID,? AS ADMINUSERNAME,? AS AUDITREASON,? AS BACKUPIDEAID  FROM DUAL) cpai
ON (cpa.keyid=cpai.keyid AND cpa.ideaid=cpai.ideaid)
WHEN NOT MATCHED THEN
INSERT
VALUES (cpai.OPID, cpai.ACCOUNTID, cpai.GROUPID, cpai.IDEAID, cpai.KEYID,
cpai.CHECKSTATUS, cpai.CREATEDATE, cpai.REFUSEREASON, cpai.ADMINUSERID, cpai.ADMINUSERNAME,
cpai.AUDITREASON,cpai.BACKUPIDEAID)

为了在同时使用PreparedStatement的时候,将这25W条sql降下来,重构应用程序如下:在应用程序中形成ideaid-keylist的集合,针对每个idea对应的key做下面的操作,执行sql数目=idea的数目.

INSERT INTO CPC.CPCPARTNERAUDIT (OPID,ACCOUNTID,GROUPID,IDEAID,KEYID,CHECKSTATUS,CREATEDATE,REFUSEREASON,ADMINUSERID,ADMINUSERNAME,AUDITREASON,BACKUPIDEAID)(SELECT   A.*FROM   (SELECT   GREATEST (I.OPID, C.OPID) AS OPID,I.ACCOUNTID,I.CPCGRPID,I.CPCIDEAID,C.CPCID,1 AS CHECKSTATUS,SYSDATE AS CREATEDATE,'自动审核通过' AS REFUSEREASON,0 AS ADMINUSERID,'自动审核' AS ADMINUSERNAME,'自动审核通过' AS AUDITREASON,NULL AS BACKUPIDEAIDFROM   CPC.CPCIDEA I, CPC.CPC CWHERE       I.CPCGRPID = C.CPCGRPIDAND I.CPCIDEAID = ?AND C.CPCID IN (?)UNION ALLSELECT   GREATEST (I.OPID, C.OPID) AS OPID,C.ACCOUNTID,I.GROUPID,I.AUDITIDEAID AS CPCIDEAID,C.CPCID,1 AS CHECKSTATUS,SYSDATE AS CREATEDATE,'自动审核通过' AS REFUSEREASON,0 AS ADMINUSERID,'自动审核' AS ADMINUSERNAME,'自动审核通过' AS AUDITREASON,I.IDEAID AS BACKUPIDEAIDFROM   CPC.CPCIDEAMODI I, CPC.CPC CWHERE       I.GROUPID = C.CPCGRPIDAND I.AUDITIDEAID = ?AND C.CPCID IN (?)) AWHERE   NOT EXISTS(SELECT   P.KEYID, P.IDEAIDFROM   CPC.CPCPARTNERAUDIT PWHERE   A.CPCIDEAID = P.IDEAID AND A.CPCID = P.KEYID))

大数据量查询的二种方式:

1. 一种全部查询到内存,然后使用subList, subList的场景比如in参数的限制.

.....int group = passedPartners.size() % IDS_PER_BATCH == 0 ? passedPartners                    .size()/ IDS_PER_BATCH                    : (passedPartners.size() / IDS_PER_BATCH + 1);

for (int i = 0; i < group; i++) {final List<CpcPartnerDTO> batchPassedPartners;if ((i + 1) * IDS_PER_BATCH > passedPartners.size()) {                    batchPassedPartners = passedPartners.subList(i* IDS_PER_BATCH, passedPartners.size());                } else {                    batchPassedPartners = passedPartners.subList(i* IDS_PER_BATCH, (i + 1) * IDS_PER_BATCH);                }                doInFacade(batchPassedPartners, AuditElement.PARTNER,                        Action.INS_AUDIT_ELEMENT);            }......

2. 直接使用数据库的分页sql获得子集.而不在内存中操作. 这样的好处是将子集放到一个中间结果里,每次再将中间结果合并到目标结果集.避免内存中同时出现二个大的结果集.

......
for (int pageNo = 1; pageNo <= totalPageCount; pageNo++) {
doPage(sql, pageNo, set);
}

......

private void doPage(String sql, int pageNo, Set<String> set) {
long t1 = System.currentTimeMillis();
final int startIndex = PageUtil.getStartOfPage(pageNo, pageSize);
String sqlLimit = PageUtil.getLimitString(sql, true);
Object[] obj = new Object[] { startIndex, startIndex + pageSize };
List<String> list = jdbcTemplateCpc.query(sqlLimit, obj,
new RowMapper() {

@Override
public Object mapRow(ResultSet rs, int arg1)
throws SQLException {
return "" + rs.getString(2) + rs.getString(1);
}

});
set.addAll(list);
long t2 = System.currentTimeMillis();
logger.info("第" + pageNo + "次查询数据量" + list.size() + ",set中现有"
+ set.size() + "条记录,耗时" + ((t2 - t1) / 1000) + "秒");
}

大数据量情况程序处理技巧相关推荐

  1. 【315期】面试官问:在大数据量情况下,如何优化 ElasticSearch 查询?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每一天进步一点点,是成功的开始... 在数据规模 ...

  2. 请你简单介绍一下ArrayList和LinkedList的区别及大数据量情况下的插入效率对比

    请你简单介绍一下ArrayList和LinkedList的区别 ArrayList采用数组实现的,查找元素的效率比LinkedList高. LinkedList采用双线链表实现,插入和删除的效率比Ar ...

  3. python解析excel内存溢出_phpExcel大数据量情况下导出内存溢出解决

    1.将单元格数据序列化后保存在内存中 PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized; 2.将单元格序列化后再进行Gzi ...

  4. 大数据量下水晶报表的实现及显示过程中的进度条显示讨论

    最近一段收到的反馈中,有几位是问到在应用程序中使用水晶报表时,大数据量情况下因为等待时间过长,给用户的感觉不好 所以想增加一个进度条,给用户一个比较直观的印象. 本文针对此问题而生,但是并没有一个像样 ...

  5. MySQL数据库如何解决大数据量存储问题

    FROM http://blog.csdn.net/likika2012/article/details/38816037 各位高手您们好,我最近接手公司里一个比较棘手的问题,关于如何利用MySQL存 ...

  6. java导出Excel增加下拉框选项,解决小数据量和大数据量下拉框选项的问题

    文章目录 java导出Excel增加下拉框选项 一.小数据量情况 二.大数据量情况 java导出Excel增加下拉框选项(java结合easyExcel) 添加传参模型ConsumablesAddDT ...

  7. 好名远扬 - 尝试让大数据量与大运算量程序运行在手机上

    该程序有两个特点:1,就CLDC角度而言数据量算比较大了;2,有一定量的运算与逻辑推理.写本程序的主要目的就是尝试让大数据量与大运算量程序运行在手机上(Heap Size: 512K~1024K).程 ...

  8. 【送书福利-第四期】从程序员到架构师:大数据量、缓存、高并发、微服务、多团队协同等核心场景实战书籍

    大家好,我是洲洲,欢迎关注,一个爱听周杰伦的程序员.关注公众号[程序员洲洲]即可获得10G学习资料.面试笔记.大厂独家学习体系路线等-还可以加入技术交流群欢迎大家在CSDN后台私信我! 送书福利-第四 ...

  9. Java8 Stream 数据流,大数据量下的性能效率怎么样?

    今日推荐程序猿惯用口头禅,你被击中了吗? 常见代码重构技巧(非常实用) B站,牛啊. 程序员缺乏经验的 7 种表现 2021年4月程序员工资统计:平均14596元,南京程序员收入挤进一线. 来源:bl ...

最新文章

  1. 转载 想要在项目中引入其他项目的方法为
  2. 仿BlogEngine.NET的cnBlog主题
  3. Java基础点:多线程
  4. kernel和filter这两个概念在CNN中的区别以及卷积核与卷积层的关系
  5. Pytorch有什么节省内存(显存)的小技巧?
  6. blob类型对象转为file类型对象
  7. smartphone软件的安装方法
  8. Mcafee之我见 * 一个木马引发的“麦咖啡”
  9. 百亿级全网舆情分析系统存储设计
  10. 利用Udacity模拟器实现自己的自动驾驶小车
  11. Intel 处理器型号数字和字母含义解析
  12. [QCTF2018]Xman-RSA
  13. macos双系统 wintogo_aigo固态硬盘,轻松实现macOS运行Windows双系统
  14. bootstrap表格标题Caption位于表格下方的原因
  15. 激光计算机是谁发明的,五个难以解释的古发明,第四个是计算机祖宗,第五个激光武器雏形...
  16. 酸奶糖酸比的计算机控制,PAL-BX丨ACID F5 五种水果糖酸度计
  17. PHP - 什么是 PHP? 为什么用 PHP? 有谁在用 PHP?
  18. SCORM 基础知识
  19. 上汽董事长称不接受与华为合作自动驾驶;曝OPPO给离职员工补发年终奖,此前遭克扣;Google Play 将启用AAB格式应用...
  20. Windows远程桌面服务漏洞(CVE-2019-0708)复现测试

热门文章

  1. MySQL 得到数据库的大小
  2. OpenSTA -- 开源测试工具软件
  3. mysql 主从复制 博客园_mysql主从复制
  4. SharingSphere 源码解析 -- 真实SQL生成探索
  5. 鸿蒙电视是无线么,鸿蒙系统首秀,在自家设备上和普通电视大不相同赵崇带你走世界...
  6. tomcat运行出现问题(Starting Tomcat v8.0 Server at localhost' has encountered a problem.)
  7. linux 查看内存消耗情况,Linux终端:用smem查看内存占用情况
  8. Python标准库中的zipfile
  9. MySQL删除重复数据实例
  10. MySQL 添加字段报错1005 Can‘t create table ‘#sql-12d23_4bd‘ (errno: 28)