我对服务器没有权限,可能有人更改了一些设置。
问题已经不存在了。
简而言之:
s.executeQuery(sql)
在Tomcat Servlet中运行非常缓慢。- 相同的查询在同一台机器上的简单Java程序中运行良好。
- 并非所有查询在Servlet中都很慢。只有一些较大的查询会缓慢。
- 在另一台机器上运行相同的Servlet速度很快。
更新
请阅读下文的更新!我有一个
servlet
通过JSON执行SQL请求并返回结果。由于某些原因,一些请求需要花费大量时间来执行,但是当我在任何Oracle SQL客户端中运行它们时,它们几乎立即完成。我指的是相同SQL的1秒与5分钟之间的巨大差异(这并不复杂)。
如何解释这种情况? 是否有方法可以提高基于Java的SQL请求的性能?
我正在使用传统的查询执行方式:
java.sql.Connection conn = null;
java.sql.Statement s = null;
ResultSet rs = null;
String dbDriver = "oracle.jdbc.driver.OracleDriver";
String dbConnectionString = "jdbc:oracle:thin:@" + dbHost + ":" + dbPort + ":" + dbSid;
Class.forName(dbDriver).newInstance();
conn = DriverManager.getConnection(dbConnectionString, dbUser, dbPass);
s = conn.createStatement();
s.setQueryTimeout(9999);
rs = s.executeQuery(newStatement);
ResultSetMetaData rsmd = rs.getMetaData();
// Get the results
while (rs.next()) {
// collect the results
}
// close connections
我尝试了ojdbc14和ojdbc6,但没有任何区别。
更新1: 在我的客户端机器上,在本地Java项目(不是servlet)中尝试了相同的SQL,结果立即返回。因此,我认为问题来自于我的servlet或Tomcat配置?
更新2: 罪魁祸首确实是rs = s.executeQuery(mySql); 我尝试使用preparedStatement替换,但没有任何区别。
更新3: 我创建了一个在本地Tomcat上运行的新Servlet,查询迅速返回。因此,问题来自于我的生产服务器或Tomcat配置。有什么配置项可能会影响这个吗?
更新4: 我在一个普通的Java程序中尝试了相同的代码(仍然在同一台服务器上),结果非常快。因此,问题来自于servlet本身(或Tomcat?)。仍然不知道该怎么做,但我缩小了范围 :)
更新5: Jstack显示以下内容(从我的servlet开始,其余部分被剪切)
"http-8080-3" daemon prio=3 tid=0x00eabc00 nid=0x2e runnable [0xaa9ee000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at oracle.net.ns.Packet.receive(Packet.java:311)
at oracle.net.ns.DataPacket.receive(DataPacket.java:105)
at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:305)
at oracle.net.ns.NetInputStream.read(NetInputStream.java:249)
at oracle.net.ns.NetInputStream.read(NetInputStream.java:171)
at oracle.net.ns.NetInputStream.read(NetInputStream.java:89)
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:123)
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:79)
at oracle.jdbc.driver.T4CMAREngineStream.unmarshalUB1(T4CMAREngineStream.java:429)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:397)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:210)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:30)
at oracle.jdbc.driver.T4CStatement.executeForDescribe(T4CStatement.java:762)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:925)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1104)
at oracle.jdbc.driver.OracleStatement.executeQuery(OracleStatement.java:1309)
- locked <0xe7198808> (a oracle.jdbc.driver.T4CConnection)
at oracle.jdbc.driver.OracleStatementWrapper.executeQuery(OracleStatementWrapper.java:422)
我卡在了java.net.SocketInputStream.socketRead0(Native Method)
这个位置?