Lotus и Oracle (jdbc)

Тема в разделе "Lotus + Java + LS2J", создана пользователем Dymytry, 22 июн 2010.

  1. Dymytry

    Dymytry Гость

    Граждане, возникла такая задача: сравнить вид в Лотусе и таблицу в Оракле на одинаковость. Сверяю их по некоему ID который есть и там и там. Делаю через JDBC. Но вот какое дело: число записей - около 100тыс. И некоторые отчеты работают крайне долго! Особенно тот который идет по Лотусу и для каждого Лотус документа делает Оракл запрос, то есть:
    Код (Text):
    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) Есть другие пути решения моей задачи?
     
  2. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Если сравнение выполняется на стороне Лотуса, то, КМК, лучше вытянуть все записи из Оракла и перебирать их по порядку, сравнивая с информацией Лотуса. В Лотусе создать представление с первым сортированным столбцом с ID, создавать навигатор и бежать по entry.
     
  3. Dymytry

    Dymytry Гость

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

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    загнать обе стороны в свои самописные классы и делать сравнение исключительно в ОЗУ, будет на порядок шустрее :)
     
  5. K-Fire

    K-Fire Гость

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

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
  7. Constantin A Chervonenko

    Constantin A Chervonenko Well-Known Member

    Регистрация:
    30 май 2006
    Сообщения:
    1.291
    Симпатии:
    0
    Получить ВСЕ записи из Оракла одним запросом (коллекцию, упорядоченную по ID); и в LND получить аналогичную коллекцию (по тому-же ID). И параллельно по ним..
     
  8. Dymytry

    Dymytry Гость

    Что-то пока не очень... 2тыс записей идут минут 5. Основная задержка - там где я перевожу ResultSet в ArrayList:
    Код (Text):
       
    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;
    }
     
  9. nvyush

    nvyush Lotus team
    Lotus team

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

    Dymytry Гость

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

    nvyush Lotus team
    Lotus team

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

    K-Fire Гость

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

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


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

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

    Dymytry Гость

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

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

    Код (Text):
            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);
    }
    }
    }
     
  14. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    А чем http://codeby.net/ipb.html?s=&sh...st&p=175222 не понравилось? Должно существенно быстрее работать.
    Допустим, размер оракловского списка m, лотусового n, тогда в предложенном варианте будет один проход по списку n и один проход по списку m. В Вашей же реализации получается либо m проходов по списку n, либо n проходов по списку m. Вот и считайте.

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

    K-Fire Гость

    OracleList и LotusList это ArrayList? Попробуйте на HashSet заменить, я так понимаю что значения вы в любом случае уникальные берете?
     
  16. Dymytry

    Dymytry Гость

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

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

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

Поделиться этой страницей