sql大字段Lob查询优化,防止内存溢出!

来源:互联网 发布:下载文华财经软件 编辑:程序博客网 时间:2024/04/20 20:00

 今天在系统中,阅读一个博文的时候,突然系统崩溃了,查看后台日志才知道,内存溢出了。内存溢出问题很严重,一定要搞定。

     首先要复现问题,找到规律,多次测试发现,只有查看其中一个博文的时候,系统会100%内存溢出,别的博文ok。这就表明是这篇博文的内容有问题,比较发现这个博文的内容比较大。因为是博文的内容,所以我在设计数据库的时候,定义为@Lob类型


// 博文内容

@Lob

@Basic(fetch = FetchType.LAZY)

@Column(name = "content")

private String content;

这就说明Hql在查询大字段的时候,内存溢出了。


我的解决步骤:

(1)首先我考虑在hibernate配置上做文章,看看有没有对应的策略。

找到了对应的文章

在MySQL中可以实现,即每次从服务器端读取一定量的数据,而不是一次性读完。 
需要的配置: 
在获得JDBC连接的时候加入参数: 
emulateLocators=true 以及 locatorFetchBufferSize=1048576 
说明: 
emulateLocators 说明获取BLOB的时候,不一次加载完。 
locatorFetchBufferSize 每次读取的大小(字节)
 

但是我加上之后,还是照样溢出!


(2)我又想到了博文内容文件存储,将博文内容写到服务器的txt文件中。

这没有什么难度,但是读取并展示到前台就有难度了,网上有javascript读取文件的例子,oFso = new ActiveXObject("Scripting.FileSystemObject");  但是这种方法好像只能兼容IE浏览器,所以这个思路我又放弃了。


(3)还是考虑优化Hql语句吧

------如果前台没必要展示大字段的话,可以这样自定义Hql语句

String hql = "select new Article(a.id,a.title,a.isTop,a.isOpen,a.isReprint,a.isHasAttachment,a.urlAttachment,a.attachmentFilename,a.praiseCount,a.replyCount,a.readCount,a.creationTime,a.creationTimeStr,a.user,a.category) from  Article a  where a.id = ?";

当然前提条件是:Article实体中必须有这些属性的构造器。

-------如果要获取大字段,可以考虑分N次获取

String hql1 = "select new Article(SUBSTRING(content,1,1000000)) from Article a where a.id = 50 ";

String hql2 = "select new Article(SUBSTRING(content,1000000)) from Article a where a.id = 50 ";

当然前提条件是:Article实体中必须有属性content的构造器。

实践证明,这种方案可取。

0 0
原创粉丝点击