Lotus и Oracle (jdbc)

  • Автор темы Dymytry
  • Дата начала
D

Dymytry

#1
Граждане, возникла такая задача: сравнить вид в Лотусе и таблицу в Оракле на одинаковость. Сверяю их по некоему ID который есть и там и там. Делаю через JDBC. Но вот какое дело: число записей - около 100тыс. И некоторые отчеты работают крайне долго! Особенно тот который идет по Лотусу и для каждого Лотус документа делает Оракл запрос, то есть:
Код:
query = "Select DESCRIPTION from MAXIMO.EQUIPMENT where ROWSTAMP = " + key + "";
state = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = state.executeQuery(query)
И так 100тыс. раз :) Я пока не дождался результата :) работает на сервере.

(1) Можно это как-то убыстрить? (например - я могу немножко ограничить область поиска в Оракл через дополнительный запрос. но я не умею искать ВНУТРИ ResultSeta. это возможно вообще?)
(2) Есть другие пути решения моей задачи?
 

nvyush

Lotus team
22.04.2009
2 317
0
#2
Если сравнение выполняется на стороне Лотуса, то, КМК, лучше вытянуть все записи из Оракла и перебирать их по порядку, сравнивая с информацией Лотуса. В Лотусе создать представление с первым сортированным столбцом с ID, создавать навигатор и бежать по entry.
 
D

Dymytry

#3
Но мне надо сравнение в обе стороны. То есть я не могу пройти только по записям Оракла - надо понять есть ли лотус документы для которых нет записей в Оракле... разве что пройтись по Ораклу и пометить найденные документы в Лотусе и поместить непомеченные в вид?..
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
17
#4
загнать обе стороны в свои самописные классы и делать сравнение исключительно в ОЗУ, будет на порядок шустрее :)
 
K

K-Fire

#5
При проходе по оракловому резалтсету, добавляй ключи в List. Потом когда 2й проход по лотусовому вью делаешь - используй этот список для сравнения.
Все должно работать очень быстро.
 
30.05.2006
1 345
11
#7
Получить ВСЕ записи из Оракла одним запросом (коллекцию, упорядоченную по ID); и в LND получить аналогичную коллекцию (по тому-же ID). И параллельно по ним..
 
D

Dymytry

#8
Что-то пока не очень... 2тыс записей идут минут 5. Основная задержка - там где я перевожу ResultSet в ArrayList:
Код:
ArrayList resultSetToList(ResultSet rs, int columnIndex) throws SQLException{

//get resultset count
rs.last();
int size = rs.getRow();
rs.beforeFirst();

ArrayList results = new ArrayList(size);

while (rs.next()){
results.add(rs.getString(columnIndex));
}

return results;
}
 

nvyush

Lotus team
22.04.2009
2 317
0
#9
Что-то пока не очень... 2тыс записей идут минут 5. Основная задержка - там где я перевожу ResultSet в ArrayList:
Не переводите. Судя по условию задачи можно сделать так:
1. Берём запись Оракла
2. Берём энтри Лотуса.
3. Сравниваем.
4. Если ИД Оракла > ИД Лотуса, запоминаем отсутствующий в Оракле ИД Лотуса, берём следующий энтри Лотуса. п. 3.
5. Если ИД Оракла < ИД Лотуса, запоминаем отсутствующий в Лотусе ИД Оракла, берём следующую запись Оракла. п. 3.
6. (ИД Оракла = ИД Лотуса) - запоминаем одинаковый ИД, берём следующие запись Оракла и энтри Лотуса. п. 3.
Повторять, пока не кончатся записи и/или энтри.
Как-то так.
 
D

Dymytry

#10
Я даже точнее скажу: основная задержка - на проход через ResultSet. Даже если добавить в агента пустой проход по нему, то это +5 мин для 2тыс. записей. А у меня есть вид где их 60 тыс....
 

nvyush

Lotus team
22.04.2009
2 317
0
#11
КМК, это лишнее:
Код:
	rs.last();
int size = rs.getRow();
rs.beforeFirst();
Позиционироваться на последнюю запись, чтобы определить число записей, и потом переходить обратно к первой тоже отнимает время. К тому же обычно последовательный рекордсет открывается быстрее. Можно, в принципе первым запросом посчитать записи, потом открыть рекордсет с записями, но нет гарантии, что между запросами число записей не изменится.
 
K

K-Fire

#12
Вообще странно что так медленно работает. Навигация по резалтсету не должна быть такой тормозной.

Инициализировать ArrayList размером совсем не обязательно, коллекция это делает автоматически.


Ради забавы написал почти аналогичный агент, выборка 8500 тыс. записей с локальной MySQL базы. Отрабатывает за 1 секунду. Отсюда можно сделать вывод что у вас какие-то проблемы либо с базой, либо с драйвером.

Код для создание коннекшна и запрос сам покажите.
 
D

Dymytry

#13
Как там было у Beatles - I have to admit its getting better, its getting better all the time ;)

Нашел 2 хрени: я исторически сделал ResultSet изменяемым и в разные стороны гоняемым. Кроме того исправил проход по докам проходом по энтриям, что раньше сделать поленился.
Сейчас все работает быстро кроме вот этой части, она занимает 15 мин. для 40тыс. записей (для одного reportType). Как думаете, это ок?

Код:
		if (reportType.equals("DOMINO2ORACLE")) {
//DOMINO -> ORACLE

for (k=0; k< LotusList.size(); k++) {
Object o = LotusList.get(k);
if (!OracleList.contains(o)) {
ResultList.add(o);
}
}

} else {
//ORACLE -> DOMINO
for (k=0; k< OracleList.size(); k++) {
Object o = OracleList.get(k);
if (!LotusList.contains(o)) {
ResultList.add(o);
}
}
}
 

nvyush

Lotus team
22.04.2009
2 317
0
#14
Сейчас все работает быстро кроме вот этой части, она занимает 15 мин. для 40тыс. записей (для одного reportType). Как думаете, это ок?
А чем http://codeby.net/ipb.html?s=&sh...st&p=175222 не понравилось? Должно существенно быстрее работать.
Допустим, размер оракловского списка m, лотусового n, тогда в предложенном варианте будет один проход по списку n и один проход по списку m. В Вашей же реализации получается либо m проходов по списку n, либо n проходов по списку m. Вот и считайте.

P.S. Плюс экономия времени на отсутствие необходимости загонять данные в списки.
 
K

K-Fire

#15
Как там было у Beatles - I have to admit its getting better, its getting better all the time ;)

Нашел 2 хрени: я исторически сделал ResultSet изменяемым и в разные стороны гоняемым. Кроме того исправил проход по докам проходом по энтриям, что раньше сделать поленился.
Сейчас все работает быстро кроме вот этой части, она занимает 15 мин. для 40тыс. записей (для одного reportType). Как думаете, это ок?
OracleList и LotusList это ArrayList? Попробуйте на HashSet заменить, я так понимаю что значения вы в любом случае уникальные берете?
 
D

Dymytry

#16
Получилось! Спасибо всем кто помогал! Время работы - не более минуты.

В итоге:
- оптимальный алгоритм, как посоветовал nvy
- надо было внимательнее смотреть на ResultSet: я инициализировал его изменяемым и гоняемым в разные стороны т.к. до этого игрался с JDBC
- ходить по энтри а не по докам

А чем мне поможет hashset? Я его засортировать не смогу. А если делать TreeSet то придется взятые элементы удалять чтобы перейти к следующему.