Однако по необъяснимым причинам сегодня утром производительность увеличилась для двух моих запросов, которые раньше были медленными. Понятия не имею почему.
У меня нет прав на сервер, может кто-то что-то менял.
Проблемы больше нет.
В двух словах:
- s.executeQuery(sql) работает очень медленно в сервлете tomcat на сервере
- Тот же запрос отлично работает без сервлета (простая программа Java) на той же машине
- Не все запросы в сервлете выполняются медленно. Только несколько больших делают
- Тот же сервлет работает быстро на другой машине
ОБНОВЛЕНИЯ
Пожалуйста, читайте обновления под текстом!
У меня есть servlet
, который выполняет запросы SQL и отправляет результаты через JSON. По какой-то причине выполнение некоторых запросов занимает огромное количество времени, но когда я запускаю их в любом клиенте Oracle SQL, они выполняются в кратчайшие сроки.
Я говорю о разнице в 1 секунду и 5 минут для одного и того же SQL (это не так сложно).
Как это можно объяснить? Есть ли способ улучшить производительность SQL-запроса на основе Java?
Я использую традиционный способ выполнения запросов:
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: я попробовал тот же SQL в локальном проекте Java (не сервлете) на своем клиентском компьютере и сразу же получил результаты. Итак, я предполагаю, что проблема связана с моим сервлетом или конфигурацией tomcat?
ОБНОВЛЕНИЕ 2: виновником действительно является rs = s.executeQuery(mySql); Вместо этого я попытался использовать подготовленный статемент, но разницы нет.
ОБНОВЛЕНИЕ 3: я создал новый сервлет, работающий на локальном Tomcat, и запрос возвращается быстро. Таким образом, проблема исходит от моего производственного сервера или конфигурации Tomcat. Любые идеи, какие элементы конфигурации могут повлиять на это?
ОБНОВЛЕНИЕ 4: я попробовал тот же код в обычной Java-программе вместо сервлета (все еще на том же сервере), и результаты приходят быстро. Следовательно, проблема исходит от самого сервлета (или Tomcat?). Пока не знаю, что делать, но я сузил его :)
ОБНОВЛЕНИЕ 5: Jstack показывает следующее (он начинается там, где находится мой сервлет, остальное я вырезал)
"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)
?