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

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

Dymytry

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

ToxaRat

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

K-Fire

Гость
#5
При проходе по оракловому резалтсету, добавляй ключи в List. Потом когда 2й проход по лотусовому вью делаешь - используй этот список для сравнения.
Все должно работать очень быстро.
 

Constantin A Chervonenko

Well-Known Member
Lotus team
30.05.2006
1 333
4
#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

Well-Known Member
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

Well-Known Member
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

Well-Known Member
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 то придется взятые элементы удалять чтобы перейти к следующему.