`
java-xb
  • 浏览: 124485 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

小程序测试Mysql 和access数据库性能,引发了一些问题,寻求解决。

阅读更多
我在做一个特征词的数据挖掘小测试,我使用java+access+jdbc进行开发的。
需求如下:
有一个文本集,文本集就是许多txt文本,文本内容大致如下:
盛名/n  之下/f  ,/w  其实难副/i  。/w  哎/e  ,/w  垃圾/n  书/n  。/w 

文本格式基本都是词+词性标示,例如:垃圾+/n
文本集大小为1529,即1529个文本文件。
计算每一个词在文本集中出现的次数,有些词不需要计算。

我首先选用access数据库,因为是一个小型的统计,所以我选用了access,用的是jdbc+odbc访问数据库
建立两张表,设计如下:

keyword表  存放词的统计
create table keyword
  (
  Id 		int(4) auto_increment not null primary key,
  Name 		varchar(50) not null,       //词的名称
  Times  	         int(4),			//词在文件集中出现的次数
  ClassLabelId    int(4),			//词的词性标示id
  count	 	int(4)			//文本集大小
  ); 

stopword表    存放不需要进行统计的词
create table stopword
( 
  Id 		int(4) auto_increment not null primary key,
  Name   	         varchar(50) not null,  //词的名称
  ClassLabelId     int(4)
);

建表语句是我用mysql进行测试时写的。

我把每个表(对应一个类)写了他们的dao操作,即增删改查操作。每个操作使用了打开数据库连接,关闭数据

库连接操作。

写完程序,我运行了一下,感觉还行,就是速度超慢,花了近半个小时才把1529个文件给统计完,我后来进行

了代码重构。发现运行速度提高了一点,但是感觉还是慢,后来在网上找了许多关于提高速度的帖子,又把代码重构了一下,感觉变化不大,说实话我经验不多,我从来没见过统计一个文本集中词的出现次数就需要20分钟的程序
。我后来想到了是不是数据库存储速度的问题,所以我想用mysql试试,果然用mysql进行测试。
在用mysql进行测试时,遇到了mysql中文乱码问题,在网上搜搜了就解决了,大家可以看我发表的mysql中文乱码问题的帖子。
换成mysql后,一运行,发现速度很快,我很高兴,不过没等我高兴几分钟,程序就报错,错误如下:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The driver was unable to create a 

connection due to an inability to establish the client portion of a socket.

This is usually caused by a limit on the number of sockets imposed by the operating system. This 

limit is usually configurable. 

For Unix-based platforms, see the manual page for the 'ulimit' command. Kernel or system 

reconfiguration may also be required.

For Windows-based platforms, see Microsoft Knowledge Base Article 196271 (Q196271).
        at sun.reflect.GeneratedConstructorAccessor10.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance

(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2103)
        at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:718)
        at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
        at sun.reflect.GeneratedConstructorAccessor6.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance

(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
        at java.sql.DriverManager.getConnection(DriverManager.java:582)
        at java.sql.DriverManager.getConnection(DriverManager.java:185)
        at fc.common.DBManager.getMySqlConnection(DBManager.java:48)
        at fc.dao.KeywordDao.getByName(KeywordDao.java:82)
        at fc.common.FcManager.countWordTimes(FcManager.java:44)
        at fc.common.FcManager.Tongji(FcManager.java:309)
        at fc.common.FcManager.main(FcManager.java:387)
Caused by: java.net.BindException: Address already in use: connect
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
连接数据库失败
数据库连接失败
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
        at java.net.Socket.connect(Socket.java:529)
        at java.net.Socket.connect(Socket.java:478)
        at java.net.Socket.<init>(Socket.java:375)
        at java.net.Socket.<init>(Socket.java:218)
        at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:253)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:280)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2026)
        ... 15 more
Exception in thread "main" java.lang.NullPointerException
        at fc.dao.KeywordDao.getByName(KeywordDao.java:117)
        at fc.common.FcManager.countWordTimes(FcManager.java:44)
        at fc.common.FcManager.Tongji(FcManager.java:309)
        at fc.common.FcManager.main(FcManager.java:387)
Java Result: 1

错误提示大致是这样的:不能创建连接,数据库连接失败。我想是不是程序写错了,哪个地方没有打开连接或者关闭连接不对。
可是仔细一想,应该不是,如果是程序错了,那在刚开始就应该报错,因为我每计算一个文本都是调用同一个方法,都过了好多文本才报错,这样情况应该不存在,我是这么认为的。

我在网上也搜索类似的错误,果然有。看了几个帖子,发现都是说服务器没有设置连接池,需要一个连接池。

我很无奈,我就写了一个小测试程序,没有用到服务器,所以无法设置连接池。可能是我没经验,也许有那种不在服务器上的连接池,我搜了搜,没发现好例子,我放弃了连接池的思路,在搜索中我想到了hibernate,我又把程序改成用hibernate访问数据库。结果没有报错,而且速度很快,我高兴的甚至把我的兴奋传到群里。
我给群里说:hibernate速度比jdbc快。
结果,群里说:你是初学者吧,那是你jdbc写的有问题 等等。
我也感觉是我写的jdbc有问题,我想是不是网上有好的jdbc,结果没找到,如果谁有好的给我发一份 邮箱:zh_xb2007@126.com,谢谢了!!!
我查看了代码,发现程序中每读取一个词都进行两次或者三次打开连接和关闭连接,是不是频繁的打开连接和关闭连接造成的错误,是不是mysql不能承受这种频繁的打开或者关闭,为何不把这样的操作放在计算每个文本的模块里面,

对于一个文本内容,可以看做一个业务逻辑,我想是不是应该把打开数据库连接和关闭数据库连接放在一个业务逻辑里面。于是我把代码修改了一下,再次运行,结果:没有报错,顺利运行,而且速度也快。我又笑了,没白费力气。
后来我又把连接改回去了,又重新连接了access,还是那个思路:把打开数据库连接和关闭数据库连接放在一个业务逻辑里面。
结果令我吃惊,居然报错了,报错内容是:客户端工作量过大。我又晕了,难道数据库不能进行大批量的更新操作?
我在网上搜了搜这个错误,都是说odbc的问题,最终没有解决这个问题。
我只好把打开数据库连接和关闭数据库连接放在一个原子操作里面,即增删改查操作。结果没有报错,速度也没提升。


测试结果如下:mysql存取数据速度确实比access高,但是那个错误是不是由于没有连接池或者频繁打开关闭连接所致,acess报客户端工作量过大的错误,这些都还没搞懂。


我附件里面有要测试的一个文本集,里面分为正面和反面两个文件夹。加起来为一个文本集
有兴趣的可以进行测试下,看看怎么样,不懂需求的请回帖给我。

希望大家给指点,拍砖都行。谢谢了



  • xl.rar (255.7 KB)
  • 下载次数: 11
分享到:
评论
3 楼 lusx 2011-09-09  
可是你上传的附件是什么东东哦!
2 楼 lusx 2011-09-09  
我也遇到了这个问题。
1 楼 java-xb 2010-08-29  
自己顶一个,没人发表一下言论

相关推荐

Global site tag (gtag.js) - Google Analytics