• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Lotus и Oracle (jdbc)

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

Dymytry

Граждане, возникла такая задача: сравнить вид в Лотусе и таблицу в Оракле на одинаковость. Сверяю их по некоему 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) Есть другие пути решения моей задачи?
 
N

nvyush

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

Dymytry

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

ToxaRat

Чёрный маг
Green Team
06.11.2007
3 332
42
BIT
0
загнать обе стороны в свои самописные классы и делать сравнение исключительно в ОЗУ, будет на порядок шустрее :)
 
K

K-Fire

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

nvyush

Посмотри пост 6
Если ID отсортированы и уникальны, то можно взять за основу.
 
30.05.2006
1 345
12
BIT
0
Получить ВСЕ записи из Оракла одним запросом (коллекцию, упорядоченную по ID); и в LND получить аналогичную коллекцию (по тому-же ID). И параллельно по ним..
 
D

Dymytry

Что-то пока не очень... 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;
}
 
N

nvyush

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

Dymytry

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

nvyush

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

K-Fire

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

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


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

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

Dymytry

Как там было у 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);
}
}
}
 
N

nvyush

Сейчас все работает быстро кроме вот этой части, она занимает 15 мин. для 40тыс. записей (для одного reportType). Как думаете, это ок?
А чем link removed не понравилось? Должно существенно быстрее работать.
Допустим, размер оракловского списка m, лотусового n, тогда в предложенном варианте будет один проход по списку n и один проход по списку m. В Вашей же реализации получается либо m проходов по списку n, либо n проходов по списку m. Вот и считайте.

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

K-Fire

Как там было у 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

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

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

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

Обучение наступательной кибербезопасности в игровой форме. Начать игру!