По необъяснимым причинам, однако, сегодня утром производительность увеличилась для двух моих запросов, которые были медленными. Понятия не имею почему.
У меня нет полномочий над сервером, возможно, кто-то что-то изменил.
Проблема не более.Время выполнения SQL намного медленнее в сервлете Tomcat, чем в обычной программе Java
В двух словах:
- s.executeQuery (SQL) работает очень медленно в TOMCAT сервлет на сервере
- же запрос работает нормально без сервлет (простой Java программы) на той же машине
- Не все запросы медленны в сервлете. Лишь немногие из них делают большие
- же сервлет работает быстро на другой машине
UPDATES
Пожалуйста, прочитайте обновления ниже текст!
У меня есть servlet
, который выполняет запросы SQL и отправляет результаты через JSON. По некоторым причинам для выполнения некоторых запросов требуется огромное количество времени, но когда я запускаю их в любом Oracle SQL Client, они выполняются в кратчайшие сроки.
Я говорю о разнице в 1 секунду против 5 минут для того же SQL (что не так сложно).
Как это можно объяснить? Есть ли способ повысить производительность Java-запроса на основе 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, но не было никакой разницы.
UPDATE 1: Я попробовал один и тот же SQL в локальном проекте Java (не сервлета) на клиентской машине, и я получаю результаты немедленно. Итак, я предполагаю, что проблема возникает из моего сервлета или конфигурации tomcat?
ОБНОВЛЕНИЕ 2: Виновником действительно Rs = s.executeQuery (MySql); Вместо этого я попытался использовать prepareStatement, но нет никакой разницы.
UPDATE 3: Я создал новый сервлет, работающий на локальном Tomcat, и запрос быстро возвращается. Поэтому проблема возникает из моего производственного сервера или конфигурации Tomcat. Любые идеи о том, какие элементы конфигурации могут повлиять на это?
UPDATE 4: Я попробовал тот же самый код в обычной Java программы вместо сервлета (до сих пор на том же сервере), и результаты приходят быстро. Ergo проблема исходит от самого сервлета (или Tomcat?).До сих пор не знаю, что делать, но я сузили его :)
UPDATE 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)
?
Является ли клиент на той же машине, что и клиент «jdbc»? Как насчет дозирования? – Jayan
Вы сравниваете на одной основе? Ваш код печатает набор результатов, вы делаете то же самое с SQL-клиентом? Обычно запрос выполняется очень быстро, но передача данных и их отображение также занимает много времени. И кстати: вы должны использовать пул соединений. Вы проверили, возможно ли время, проведенное во время входа? Еще один совет: вы можете использовать dbVisualizer для подключения к базе данных. Он написан на одном языке (Java), но оптимизирован. Таким образом, вы можете увидеть, есть ли проблема в Java/драйвер или ваш код. – Marged
, не используя подготовленные заголовки, которые будут кэшировать ваш запрос. Пожалуйста, отправьте оба запроса, иначе мы не сможем помочь. – Paizo