当前位置: 首页 > news >正文

网站建设狼盾网络营销型网站建设策划书

网站建设狼盾网络,营销型网站建设策划书,17网站一起做网店 发货慢,青岛网页建站模板问题场景Mysql数据处理类型分以下三种com.mysql.cj.protocol.a.result.ResultsetRowsStatic:普通查询,将结果集一次性全部拉取到内存com.mysql.cj.protocol.a.result.ResultsetRowsCursor:游标查询,将结果集分批拉取到内存&#x…

问题场景

Mysql数据处理类型分以下三种

com.mysql.cj.protocol.a.result.ResultsetRowsStatic:普通查询,将结果集一次性全部拉取到内存

com.mysql.cj.protocol.a.result.ResultsetRowsCursor:游标查询,将结果集分批拉取到内存,按照fetchSize大小拉取,会占用当前连接直到连接关闭。在mysql那边会建立一个临时表写入磁盘(查询结束后由mysql回收处理),会导致mysql server磁盘io飙升。

com.mysql.cj.protocol.a.result.ResultsetRowsStreaming:流式查询,将结果集一条一条的拉取进内存,比较依赖网络,可能会造成网络阻塞。占用当前mysql连接。

所以在普通查询大数据量时如果JVM内存不够用会出现OOM异常。如下测试方案

数据量20w,一条数据大概2K。

虚拟机参数 -Xmx256m -Xms256m

(1)普通查询,大概接近200多M就GC释放

(2)流式查询,不会出现内存溢出

(3)游标查询,不会出现内存溢出

执行原理—分析

参考:https://machen.blog.csdn.net/article/details/112169908

JDBC 与 MySQL 服务端的交互是通过 Socket 完成的,完整请求链路

JDBC 客户端 -> 客户端 Socket -> MySQL -> 检索数据返回 ->MySQL 内核Socket 缓冲区-> 网络-> 客户端Socket Buffer -> JDBC 客户端

普通查询的方式在查询大数据量时,所在 JVM 可能会凉凉,原因如下:

MySQL Server 会将检索出的SQL 结果集通过输出流写入到内核对应的 Socket Buffer

内核缓冲区通过 JDBC 发起的TCP 链路进行回传数据,此时数据会先进入 JDBC 客户端所在内核缓冲区

JDBC 发起 SQL 操作后,程序会被阻塞在输入流的 read 操作上,当缓冲区有数据时,程序会被唤醒进而将缓冲区数据读取到 JVM 内存中

MySQL Server 会不断发送数据,JDBC 不断读取缓冲区数据到 Java 内存中,虽然此时数据已到 JDBC 所在程序本地,但是 JDBC 还没有对 execute 方法调用处进行响应,因为需要等到对应数据读取完毕才会返回

弊端就显而易见了,如果查询数据量过大,会不断经历 GC,然后就是内存溢出

普通查询等待时间与游标查询等待时间原理上是不一致的,前者是一致在读取网络缓冲区的数据,没有响应到业务层面;后者是 MySQL 在准备临时数据空间,没有响应到 JDBC

游标查询消费完fetchSize 行数据,就需要发起请求到服务端请求

流式查询

当客户端与MySQL Server 端建立起连接并且交互查询时,MySQLServer 会通过输出流将SQL 结果集返回输出,也就是 向本地的内核对应的 SocketBuffer 中写入数据,然后将内核中的数据通过TCP 链路回传数据到JDBC 对应的服务器内核缓冲区

JDBC 通过输入流 read 方法去读取内核缓冲区数据,因为开启了流式读取,每次业务程序接收到的数据只有一条

MySQL 服务端会向 JDBC 代表的客户端内核源源不断的输送数据,直到客户端请求 Socket 缓冲区满,这时的 MySQL 服务端会阻塞

对于JDBC 客户端而言,数据每次读取都是从本机器的内核缓冲区,所以性能会更快一些,一般情况不必担心本机内核无数据消费(除非MySQL 服务端传递来的数据,在客户端不做任何业务逻辑,拿到数据直接放弃,会发生客户端消费比服务端超前的情况)

代码实现—使用

依赖

<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.1</version>
</dependency>
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.0</version>
</dependency>

流式查询

Mapper接口---返回值为void,依靠ResultHandler进行结果处理

void queryAllTest(ResultHandler<TradeOrderDO> resultHandler);

xml定义-----fetchSize为Integer.MIN_VALUE

<select id="queryAllTest" resultMap="TradeOrderOutput" resultSetType="FORWARD_ONLY" fetchSize="-2147483648">select * from eppc_db.t_trade_order
</select>

以上也可以用注解实现,如下

// @ResultType(TradeOrderDO.class)
// @Select("select * from eppc_db.t_trade_order order by Fpkid desc")//@Options(resultSetType = ResultSetType.FORWARD_ONLY,fetchSize = Integer.MIN_VALUE)void queryAllTest(ResultHandler<TradeOrderDO> resultHandler);

Service层

@Override
public List<TradeOrderDO> queryList() {List<TradeOrderDO> tradeOrderDOList = new ArrayList<>();List<String> cardIds = new ArrayList<>();AtomicInteger i = new AtomicInteger(0);tradeinfoDAO.queryAllTest(resultHandler ->{TradeOrderDO resultObject = resultHandler.getResultObject();if (i.get() % 100000 == 0){//此处做业务处理System.out.println(resultObject.getPkid());
// tradeOrderDOList.add(resultHandler.getResultObject());}i.getAndIncrement();});return tradeOrderDOList;
}

游标查询 2种方式

方式1

Mapper接口-----这种是在mapper层直接定义返回游标封装信息

//@Options(resultSetType = ResultSetType.FORWARD_ONLY,fetchSize = Integer.MIN_VALUE)//@Select("select * from eppc_db.t_trade_order")
// @ResultType(TradeOrderDO.class)Cursor<TradeOrderDO> getAllRecord();

方式2---需要在service层使用sqlSession调用

//@Options(resultSetType = ResultSetType.FORWARD_ONLY,fetchSize = Integer.MIN_VALUE)//@Select("select * from eppc_db.t_trade_order")
// @ResultType(TradeOrderDO.class)
List<TradeOrderDO> getAllRecords();

Service层---需注意加上事务注解表示该service并不是在mapper结束时结束事务,而是等整个service结束才结束事务,不然会出现只能读取到第一段游标的结果集。

@Override
@Transactional(readOnly = true)
public List<TradeOrderDO> getAllRecord() {List<TradeOrderDO> tradeOrderDOList = new ArrayList<>();Cursor<TradeOrderDO> cursor = null;SqlSession sqlSession = null;try {cursor = tradeinfoDAO.getAllRecord();//方式1调用sqlSession = sqlSessionFactory.openSession();
cursor = sqlSession.selectCursor(TradeinfoDAO.class.getName() + ".getAllRecords");//方式2调用int currentIndex = 0;Iterator<TradeOrderDO> iterator = cursor.iterator();while (iterator.hasNext()){System.out.println(iterator.next()+""+currentIndex);/*if (currentIndex % 100000 == 0){//一次业务处理System.out.println("先写入一部分数据"+iterator.next()+currentIndex);}*/currentIndex ++;}} catch (Exception e) {e.printStackTrace();} finally {if (null != cursor) {try {cursor.close();} catch (Exception e) {log.error(e.getMessage(), e);}}
if (null != sqlSession) {try {sqlSession.close();} catch (Exception e) {log.error(e.getMessage(), e);}return tradeOrderDOList;}
}

使用总结

当遇到大数据量查询时确实可以使用mybatis的游标或者游式查询,Mysql底层也支持。但这只是减缓了数据库服务器的读与传输的压力。到业务层面还是需要根据具体业务场景去分批处理,比如一条查300w数据,游式查询能支持,但也不能一起性放入java的list中,内存不够还是会溢出。这时可能就需要写一些条件一次处理多少数据,所以本质来说就是数据不一次性存储,但总有地方要把这些数据存着。不给JVM内存,那就会牺牲网络或者服务器的其它属性。


文章转载自:
http://coupe.dztp.cn
http://gandhiism.dztp.cn
http://sequencer.dztp.cn
http://otherwhere.dztp.cn
http://decidedly.dztp.cn
http://vasopressor.dztp.cn
http://opprobrium.dztp.cn
http://chastisable.dztp.cn
http://extramolecular.dztp.cn
http://inextricability.dztp.cn
http://slatter.dztp.cn
http://valorization.dztp.cn
http://chopboat.dztp.cn
http://crosspatch.dztp.cn
http://carmelite.dztp.cn
http://hymenotomy.dztp.cn
http://bitumastic.dztp.cn
http://presuppurative.dztp.cn
http://ambages.dztp.cn
http://pergola.dztp.cn
http://basketful.dztp.cn
http://keeper.dztp.cn
http://osmiridium.dztp.cn
http://desynonymize.dztp.cn
http://portance.dztp.cn
http://siangtan.dztp.cn
http://sigmoidectomy.dztp.cn
http://tractile.dztp.cn
http://posthypnotic.dztp.cn
http://implicit.dztp.cn
http://segmentation.dztp.cn
http://incompletive.dztp.cn
http://variolar.dztp.cn
http://cyclostomous.dztp.cn
http://ablaut.dztp.cn
http://difficile.dztp.cn
http://startled.dztp.cn
http://purveyance.dztp.cn
http://infrasonic.dztp.cn
http://goatmoth.dztp.cn
http://violently.dztp.cn
http://duotype.dztp.cn
http://habilitate.dztp.cn
http://warlock.dztp.cn
http://disuse.dztp.cn
http://harmost.dztp.cn
http://influencing.dztp.cn
http://gundalow.dztp.cn
http://coldstart.dztp.cn
http://swoon.dztp.cn
http://serta.dztp.cn
http://uninjurious.dztp.cn
http://valuables.dztp.cn
http://inconsonance.dztp.cn
http://conclude.dztp.cn
http://smithcraft.dztp.cn
http://wscf.dztp.cn
http://overstowage.dztp.cn
http://here.dztp.cn
http://pastille.dztp.cn
http://crewel.dztp.cn
http://crm.dztp.cn
http://plessor.dztp.cn
http://wfp.dztp.cn
http://thought.dztp.cn
http://almemar.dztp.cn
http://drowse.dztp.cn
http://fructifier.dztp.cn
http://finned.dztp.cn
http://wittily.dztp.cn
http://procaryotic.dztp.cn
http://aldan.dztp.cn
http://oahu.dztp.cn
http://pollinizer.dztp.cn
http://hypopiesis.dztp.cn
http://achromatous.dztp.cn
http://sialkot.dztp.cn
http://dilemma.dztp.cn
http://montane.dztp.cn
http://unobstructed.dztp.cn
http://herbalist.dztp.cn
http://paradisaical.dztp.cn
http://plimsoll.dztp.cn
http://entablature.dztp.cn
http://unregenerate.dztp.cn
http://cornu.dztp.cn
http://loculose.dztp.cn
http://bsn.dztp.cn
http://wonderingly.dztp.cn
http://virgilian.dztp.cn
http://thrombophlebitis.dztp.cn
http://gallia.dztp.cn
http://epoch.dztp.cn
http://copygraph.dztp.cn
http://polarisability.dztp.cn
http://omelet.dztp.cn
http://pupae.dztp.cn
http://nontoxic.dztp.cn
http://shallow.dztp.cn
http://tarada.dztp.cn
http://www.dt0577.cn/news/115158.html

相关文章:

  • 网站服务器基本要素有哪些seo怎么优化
  • 淄博外贸网站建设头条广告入口
  • 一个网站做十个二级域名什么是论坛推广
  • 中山建设监理有限公司 网站广州搜发网络科技有限公司
  • 成都网站开发哪家公司好怎么注册自己的网站域名
  • 怎么在各大网站做推广四年级2023新闻摘抄
  • 大连网站建设外包公司护肤品营销策划方案
  • 湛江市建设规划局网站网站优化北京seo
  • 室内设计师招聘简章快速优化工具
  • 做网站的经验seo网络营销推广公司深圳
  • h5 网站开发廊坊百度推广seo
  • 网站栏目页面google网站搜索
  • 互联网保险和线下保险的区别seo的方式有哪些
  • 做网站怎么让字居右河南做网站的
  • 网站建设验收评审标准怎么自己做一个网站
  • 购物网站功能模块设计微信营销软件群发
  • 域名备案关闭网站如何自己做推广
  • 班级网站 模板百度搜索结果优化
  • 如何修改网站关键词网站查询器
  • wordpress 版块关键词优化排名软件哪家好
  • 企业设计网站推荐云客网平台
  • 免费企业网站模板psd网络市场的四大特点
  • 网站通栏如何做特效html模板网站
  • 苏州网站建设报价单电商产品推广方案
  • 沈阳营销型网站制作技术舆情监控
  • 石家庄做网站建设的公司排名宽带营销案例100例
  • div使用太多影响网站收录接广告的平台推荐
  • wordpress站点一百数据卡不南京网络推广外包
  • 沈阳电子商务网站建设百度平台
  • 外贸公司网站开发网络营销推广活动有哪些