Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Сравнение СУБД Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 21 22 23 24 25 [26] 27 28 29 30 .. 34   вперед  Ctrl
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Su  [new]
c127
Guest
>Вы не поняли одного простого факта. Изначально я вообще не планировал сравнивать FO и Oracle на задаче ввода данных.

Как раз то, что Вы не собирались сравнивать я понял.

Ввод данных как раз предлагал (настаивал) не сравнивать я, но это не важно.

Импорт данных воообще ставнивать не нужно, это обычно очень редкая задача. А вот быстродействие сравнить интересно.

>Учитывая все это, советы перейти к использованию CSV или переписать код на PL/SQL могут решить проблему заливки большого объема данных (хотя насчет CSV нужны пояснения), но тогда и модель уже не будет соответствовать реальности (данные должны поступать в БД извне).

Этого я не понял. Каким образом импорт данных може сделать модель несоответсвующей реальности? Модель сама по себе, данные сами по себе. Как именно данные попадают в базу сказать вообще невозможно, может как раз импортируются из старой системы.

CSV это стандартный ОДБЦ формат. Можно исопльзовать другой. Но в принципе импорт из заранее подготовленных источников ИМХО самый простой и правильный способ, по крайней мере проще предложенного Вами. Тем более что Вы построили структуру ООБД идентичную реляционной. Хотя с другой стороны то, что предложили Вы тестирует добавление данных в базу в условиях приближенных к боевым и это могло бы быть неплохим тестом, если бы мы обсуждали ввод-вывод. Но это другая задача.

>Кстати, как это лучше всего сделать в Oracle 9i?

Что-то типа alter table [ owner.]table-name drop index index_name; или alter table [ owner.]table-name drop constraint constraint_name;

XM

>Шо, трудно написать и использовать один генератор псевдослучайных чисел?

Один для джавы и ПЛ-СКЛ-я? Не пробовал, но наверное можно при некоторых усилиях, только нет смысла. По-моему предлагаемый импорт гораздо проще и реальнее.
10 апр 05, 00:22    [1454926]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Sh
Member

Откуда: SPB
Сообщений: 1930
CSV - это просто comma separated values , одбц здесь ни при чём
10 апр 05, 00:36    [1454929]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Su  [new]
AAron
Member

Откуда: Москва
Сообщений: 4324
как я вычитал у Тома Кайта, использование запросов с явной подстановкой значений - самый лучший способ затормозить систему. Поэтому лучше использовать параметризованные запросы. Здесь вам ораклисты лучше растолкуют, как правильнее подправить код.
10 апр 05, 01:01    [1454935]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Su  [new]
XM
Guest
Alexey Rovdo

А можно выложить методику (код) и/или все константы использованные при заполнении базы?

Прикреплено - PERL - скрипт для генерации файла данных, SQL скрипт для импорта в PostgreSQL. Данные в текст. файле разделены табуляцией.

Фишка в том, что таблицы создаются без ключей и индексов, тогда данные заливаются минут 15-20, а все констрейнты и индексы создаются уже после импорта данных, шо занимает еще час.

Alexey Rovdo

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


Да уже ж назывались основные причины:
1. проверка foreign key constraint при INSERT INTO Ticket
2. SELECT 130_000 раз
3. COMMIT 130_000 раз

И воопче, вот если бы реальная многопользовательская система запрос на внесение одной записи о билете выполняла за 50ms (гут, зер гут!), то на 28 млн. билетов скока надо времени? Недели две

К сообщению приложен файл (test_gen.zip - 2Kb) cкачать
10 апр 05, 11:08    [1455026]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Su  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
c127

Импорт данных воообще ставнивать не нужно, это обычно очень редкая задача. А вот быстродействие сравнить интересно.

>Учитывая все это, советы перейти к использованию CSV или переписать код на PL/SQL могут решить проблему заливки большого объема данных (хотя насчет CSV нужны пояснения), но тогда и модель уже не будет соответствовать реальности (данные должны поступать в БД извне).

Этого я не понял. Каким образом импорт данных може сделать модель несоответсвующей реальности? Модель сама по себе, данные сами по себе. Как именно данные попадают в базу сказать вообще невозможно, может как раз импортируются из старой системы.



Я действительно не собирался сравнивать быстродействие при генерации тестовых данных. Но поднять этот вопрос меня подтолкнула проблема, с которой я столкнулся в Oracle (все проблемы FO мне понятны и ниже я их освещу). Когда я писал на коленгке свои програмульки для ввода тестовых данных, то вообще не заморачивлся с обдумыванием их оптимизации. В конце концов мне по барабану сколько времени генерятся тестовые данные, если могу запустить прогу на выходные и в понедельник вижу готовый результат, с которым уже можно экспериментировать.

Но эксперименты показали, что на объемах данных порядка 1 ГБ Oracle начинает заметно опережать FO при обработке запросов просто за счет более эффективной реализации кэширования индексов. Стало интересно, что же будет при размере базы порядка 10-20 Гб. И тут выяснилось, что избранный мною способ генерации тестовых данных не позволяет в разумные сроки сгенерировать такую базу. Вот тогда то я и заинтересовался вопросам - почему так.

Попутно в соседней ветке я высказался в том духе, что ООСУБД популярны в система реального времени поскольку позволяют быстро складировать большие объемы данных от разнообразных измерительных и контролирующих систем. Обсуждение мотивированности данного утверждения и вернула меня к рассмотрению представленной здесь проблемы - замедления Oracle при вводе данных в таблицы с большим количеством FK (пока мне кажется, что это наиболее значимый фактор, влияющий на быстродействие моего приложения).

c127

CSV это стандартный ОДБЦ формат. Можно исопльзовать другой. Но в принципе импорт из заранее подготовленных источников ИМХО самый простой и правильный способ, по крайней мере проще предложенного Вами. ...
Вы тестирует добавление данных в базу в условиях приближенных к боевым и это могло бы быть неплохим тестом, если бы мы обсуждали ввод-вывод. Но это другая задача.


А давайте пообсуждаем именно ввод-вывод. Я не отказываюсь от обсуждения быстродействия при обработке запросов, но я еще не готов делать однозначные выводы в этом вопросе. Поэтому этот вопрос лучше еще отложить. А вот обсуждение ввода-вывода именно для "боевых" условий на основе приведенного мною кода вполне может состояться (если вы не возражаете).

c127

Что-то типа alter table [ owner.]table-name drop index index_name; или alter table [ owner.]table-name drop constraint constraint_name;


Я пробовал поубирать индексы. На быстродействие конечно влияет, но не кардинально. То же самое скажу и про изменение кода в пользу переноса части задач в PL/SQL-процедуры. Так можно поднять скорость этого кода ну на 20-30%. А есть ли способ увеличить скорость на порядок?

Я привел два кода для одной задачи. Так вот первый код работает быстрее (вероятно работа с датасетами в достаточное мере оптимизирована внутри борландовских библиотек). Хочу провести эксперимент с отключением проверки ссылочной целостности (т.е. сами поля FK не удаляются из таблиц - просто они не должны проверяться при поступлении данных). Лениво рыться в оракловых доках. Может кто подскажет команду (что-то типа SET NO_CHECKCONSTRAINT) или соответствующий конфигурационный параметр, чтобы сделать это быстро и сразу для всех таблиц без существенного переписывания SQL-кода.

c127

Один для джавы и ПЛ-СКЛ-я? Не пробовал, но наверное можно при некоторых усилиях, только нет смысла. По-моему предлагаемый импорт гораздо проще и реальнее.


Согласен - пустая трата времени. А главное - простой перенос кода в PL/SQL не приведет к повышению быстродействия на порядок (а меньшее на вопрос не отвечает).
10 апр 05, 11:53    [1455048]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
SQL*Loader
Guest
А если SQLLDR к оракловой базе применить в режиме непосредственной загрузки?
10 апр 05, 13:48    [1455125]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
tygra
Member

Откуда: Тверь (Иркутск, Край)
Сообщений: 9997
Все-же, если измеряется быстродействие именно вставки некоторого большого количества данных, то давайте сначала нагенерим данные в файл, а потом уж оттуда будем тупо вставлять. Иначе измеряется скорость кода, который генерирует тестовые данные - это однако разные вещи.

-- Tygra's --
11 апр 05, 11:19    [1456325]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
tygra
Все-же, если измеряется быстродействие именно вставки некоторого большого количества данных, то давайте сначала нагенерим данные в файл, а потом уж оттуда будем тупо вставлять. Иначе измеряется скорость кода, который генерирует тестовые данные - это однако разные вещи.

-- Tygra's --


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

Мы, конечно, можем заранее сгенерировать данные для FK, и не использовать запросы по ходу заполнения таблицы Ticket. Но здесь опять таки вопрос - так ли уж это существенно влияет на производительность. Несмотря на замечания о том, что запрос "SELECT Flight.id, MAX(Seat.id) seat_id_end ..." выполняется много раз в цикле, на самом деле в первом варианте кода это не так. Запрос выполняется до всех циклов, а в цикле есть только перемещения по полученному рекордсету qds3
...
// Билеты
qds3.goToRow(j-1);
k = (qds3.getBigDecimal("seat_id_start")).intValue();
while (k <= (qds3.getBigDecimal("seat_id_end")).intValue()) { ...


Поэтому лично мне кажется, что код (даже Java-код не повлияет на скорость слишком уж сильно).

Как мне кажется, вопрос ускорения заливки тестовых данных в базу вполне решаем с помощью описанных выше методов и его мы с повестки дня снимаем. Поэтому все, что мы обсуждаем ниже касается именно вопроса сравнения быстродействия Oracle и FastObjects в условиях близких к боевым при записи большого объема, поступающих откуда-то извне, структурированных данных.
11 апр 05, 11:33    [1456396]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Su  [new]
c127
Guest
2 Alexey Sh

>CSV - это просто comma separated values , одбц здесь ни при чём

В ОДБЦ есть спецификаация этого формата, можно почитать. Она наверняка есть и в других местах, но я ее видел именно в ОДБЦ.



2 Alexey Rovdo

>>Вы тестирует добавление данных в базу в условиях приближенных к боевым и это могло бы быть неплохим тестом, если бы мы обсуждали ввод-вывод. Но это другая задача.

>А давайте пообсуждаем именно ввод-вывод.

Нет смысла обсуждать ввод-вывод, это не задача сервера, это задача клиента. У сервера есть либо добавление-удаление либо импорт-экспорт. Это разные задачи.

Я неправильно выразился. Фраза "если бы мы обсуждали ввод-вывод" лишняя и все запутывает. Я хотел сказать, что добавление данных в базу обычным образом, т.е. через кучу инсертов, может быть полезным тестом, но это не то, что мы первоначально хотели обсуждать. А вот импорт больших объемов встречается довольно редко, поэтому тестировать его в большинстве случаев бессмысленно.

>Я пробовал поубирать индексы. На быстродействие конечно влияет, но не кардинально. То же самое скажу и про изменение кода в пользу переноса части задач в PL/SQL-процедуры. Так можно поднять скорость этого кода ну на 20-30%.

Последнее похоже на правду.

А вот убивание индексов и ФК должно сказаться сильно, особенно в случае явных insert-update-delete. Так что посмотрите внимательно, может какой-нибудь индекс остался.

Еще очень сильно могут влиять настройки сервера, но это нужно говорить с ДБА. Выложите свои настройки, может кто-нибудь подскажет что подправить.
12 апр 05, 04:33    [1459122]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
Готов озвучить свои выводы по поводу именно сохранения больших массивов структурированных данных.

Тестовый код для Oracle:

import java.math.*;
import java.util.*;
import java.sql.*;
import java.io.*;

public class Avia_oracle2 {
  public static void main( String[] args )
     throws SQLException, IOException
     {
       DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
       Connection conn = DriverManager.getConnection("jdbc:oracle:oci8:@aviatest", "test", "test");
       conn.setAutoCommit(false);

       //  Массированный ввод данных
       GregorianCalendar c1 = new GregorianCalendar();
       System.out.println(c1.getTime().toString());
       System.out.println("Start dataflow ...");
       System.out.println();

       // Города
       Statement stmt = conn.createStatement();
       int i = 0;
       while (++i <= 200) {
         String qry1 = "INSERT INTO City (id, name) VALUES(" + Integer.toString(i) +
             ", 'City" + Integer.toString(i) + "')";
         stmt.executeQuery(qry1);
       }
       conn.commit();
       stmt.close();
       c1 = new GregorianCalendar();
       System.out.println(c1.getTime().toString());
       System.out.println("Cities: " + Integer.toString(i - 1));
       System.out.println();

       // Типы самолетов и месита в них
       stmt = conn.createStatement();
       Random d1 = new Random(500);
       int j, k = 0;
       i = 0;
       while (++i <= 50) {
         String qry1 = "INSERT INTO Crafttype (id, description) VALUES(" + Integer.toString(i) +
             ", 'Crafttype" + Integer.toString(i) + "')";
         stmt.executeQuery(qry1);

         // Места в самолетах
         j = 0;
         int s1 = 30 + d1.nextInt(200);
         int s2 = 100 + d1.nextInt(100);
         while (++j <= s1 + s2) {
           String qry2 = "INSERT INTO Seat (id, crafttype_id, seat_level, seat_number) VALUES(" +
               Integer.toString(++k) + ", " + Integer.toString(i) + ", " +  Integer.toString(j > s1 ? 2 : 1) +
               ", " + Integer.toString(j) + ")";
           stmt.executeQuery(qry2);
         }
       }
       conn.commit();
       stmt.close();
       c1 = new GregorianCalendar();
       System.out.println(c1.getTime().toString());
       System.out.println("Crafttypes: " + Integer.toString(i - 1));
       System.out.println("Seats: " + Integer.toString(k));
       System.out.println();

       // Рейсы
       stmt = conn.createStatement();
       i = 0;
       String descr;
       while (++i <= 2000) {
         int j1 = d1.nextInt(49) + 1; int j2 = d1.nextInt(199) + 1; int j3 = d1.nextInt(199) + 1;
         while (j2 == j3) {
           j3 = d1.nextInt(199);
         }
         String qry1 = "INSERT INTO Flight SELECT " +
             Integer.toString(i) + " id, (City1.name || '-' || City2.name) description, " +
             Integer.toString(j1) + " crafttype_id, " +
             Integer.toString(j2) + " startpoint_id, " + Integer.toString(j3) + " endpoint_id" +
             " FROM City City1 JOIN City City2 ON City2.id = " +
             Integer.toString(j3) + " WHERE City1.id = " + Integer.toString(j2);
         stmt.executeQuery(qry1);
       }
       conn.commit();
       stmt.close();
       c1 = new GregorianCalendar();
       System.out.println(c1.getTime().toString());
       System.out.println("Flights: " + Integer.toString(i - 1));
       System.out.println();

       // Персоны
        PreparedStatement pstmt =
            conn.prepareStatement("INSERT INTO Person (id, first_name, last_name) VALUES( ?, ?, ?)");
       i = 0;
       while (++i <= 2000000) {
         pstmt.setBigDecimal(1, new BigDecimal(i));
         pstmt.setString(2, "Name" + Integer.toString(i));
         pstmt.setString(3, "LastName" + Integer.toString(i));
         pstmt.executeUpdate();
       }
       conn.commit();  pstmt.close();
       c1 = new GregorianCalendar();
       System.out.println(c1.getTime().toString());
       System.out.println("Persons: " + Integer.toString(i - 1));
       System.out.println();

       // Расписание и билеты
       pstmt = conn.prepareStatement("INSERT INTO Item (id, flight_id, day) VALUES(?, ?, ?)");
       PreparedStatement pstmt2 =
           conn.prepareStatement("INSERT INTO Ticket (id, seat_id, item_id, person_id, cost) 
VALUES(?, ?, ?, ?, ?)");
       PreparedStatement pstmt3 =
           conn.prepareStatement("SELECT MIN(Seat.id) seat_id_start, MAX(Seat.id)
 seat_id_end FROM Seat INNER JOIN Flight ON Flight.crafttype_id = 
Seat.crafttype_id WHERE Flight.id = ?");

       d1 = new Random(500);
       GregorianCalendar curr_day = new GregorianCalendar(2004, 10, 30);
       GregorianCalendar end_day = new GregorianCalendar(2005, 0, 2);
       i = 1; // счетчик рейсов (элементов расписания)
       int l = 1; // счетчик билетов (броней)
       while (! (curr_day.equals(end_day))) {
         j = 0;
         while (++j <= 2000) {
           pstmt.setBigDecimal(1, new BigDecimal(i)); // id
           pstmt.setBigDecimal(2, new BigDecimal(j)); // flight_id
           pstmt.setString(3,
               (curr_day.get(Calendar.DAY_OF_MONTH) <= 9 ?
                     "0" + Integer.toString(curr_day.get(Calendar.DAY_OF_MONTH)) :
                     Integer.toString(curr_day.get(Calendar.DAY_OF_MONTH)) ) + "." +
               (curr_day.get(Calendar.MONTH) <= 8 ?
                     "0" + Integer.toString(curr_day.get(Calendar.MONTH) + 1) :
                    Integer.toString(curr_day.get(Calendar.MONTH) + 1) ) + "." +
               Integer.toString(curr_day.get(Calendar.YEAR)) );
           pstmt.executeUpdate();

           // Билеты
           pstmt3.setBigDecimal(1, new BigDecimal(j));
           ResultSet rs = pstmt3.executeQuery();
           rs.next();
           k = (rs.getBigDecimal("seat_id_start")).intValue();
           while (k <= (rs.getBigDecimal("seat_id_end")).intValue()) {
             if (! (d1.nextBoolean() & d1.nextBoolean())) {
               int j1 = d1.nextInt(1999999), j2 = 0;
               if (! (d1.nextBoolean() & d1.nextBoolean() & d1.nextBoolean())) {
                 j2 = d1.nextInt(500);
               }
               pstmt2.setBigDecimal(1, new BigDecimal(l)); // id
               pstmt2.setBigDecimal(2, new BigDecimal(k)); // seat_id
               pstmt2.setBigDecimal(3, new BigDecimal(i)); // item_id
               pstmt2.setBigDecimal(4, new BigDecimal(j1)); // person_id
               pstmt2.setBigDecimal(5, new BigDecimal(j2)); // cost
               pstmt2.executeUpdate();
               l++;
             }
             k++;
           }
           conn.commit();
           i++;
           if (d1.nextBoolean()) {
             j--;
           }
         }
         conn.commit();
         curr_day.add(Calendar.DAY_OF_MONTH, 1);
       }
       conn.commit(); pstmt.close(); pstmt2.close(); pstmt3.close();
       conn.close();
       c1 = new GregorianCalendar();
       System.out.println(c1.getTime().toString());
       System.out.println("Items: " + Integer.toString(i - 1));
       System.out.println("Tickets: " + Integer.toString(l - 1));
     }
}

Структуру БД и индексов я уже давал выше.

Тестовый код для FastObjects t7:

import com.poet.jdo.*;
import com.poet.jdo.admin.DatabaseAdministration;
import javax.jdo.*;
import avia.model.*;
import java.math.*;
import java.util.*;

public class Avia_testdata {

    public static void main( String[] args ) {

      Properties pmfProps = new Properties();

      pmfProps.put("javax.jdo.PersistenceManagerFactoryClass",
                   "com.poet.jdo.PersistenceManagerFactories");
      pmfProps.put("javax.jdo.option.ConnectionURL",
                   "fastobjects://LOCAL/Avia");
      PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(pmfProps);
      PersistenceManager pm = pmf.getPersistenceManager();

      Extent cityExtent = pm.getExtent( avia.model.City.class, true );
      Extent craftExtent = pm.getExtent( avia.model.CraftType.class, true );
      Extent itemExtent = pm.getExtent( avia.model.Item.class, true );
      Extent flightExtent = pm.getExtent( avia.model.Flight.class, true );
      Extent personExtent = pm.getExtent( avia.model.Person.class, true );

      //  Массированный ввод данных
      GregorianCalendar c1 = new GregorianCalendar();
      System.out.println(c1.getTime().toString());
      System.out.println("Start dataflow ...");
      System.out.println();

      // Города
      City city_N;
      Transaction txn = pm.currentTransaction();
      txn.begin();

      int i = 1;
      while (i <= 200 ) {
        city_N = new City();
        city_N.name = "City"+Integer.toString(i);
        //city_N.flights = new java.util.HashSet();
        pm.makePersistent(city_N);
        i++;
      }
      txn.commit();
      c1 = new GregorianCalendar();
      System.out.println(c1.getTime().toString());
      System.out.println("Cities: " + Integer.toString(i-1));
      System.out.println();


      // Типы самолетов и места в них
      CraftType crft;
      txn = pm.currentTransaction();
      txn.setRetainValues(true);
      txn.begin();

      Random d1 = new Random(500);
      int is1, is2, j;

      i = 1; int k = 1;
      while (i <= 50 ) {
        crft = new CraftType();
        crft.description = "Crafttype"+Integer.toString(i);
        crft.seats1 = new HashSet();
        crft.seats2 = new HashSet();
        pm.makePersistent(crft);

        // Места в самолетах
        j = 1;
        is1 = 30 + d1.nextInt(200);
        is2 = 100 + d1.nextInt(100);
        while (j <= is1 ) {
          crft.seats1.add(new Seat(j, 1));
          j++; k++;
        }
        while (j <= is1+is2 ) {
          crft.seats2.add(new Seat(j, 2));
          j++; k++;
        }
        i++;
      }
      txn.commit();
      c1 = new GregorianCalendar();
      System.out.println(c1.getTime().toString());
      System.out.println("Crafttypes: " + Integer.toString(i-1));
      System.out.println("Seats: " + Integer.toString(k-1));
      System.out.println();


      // Рейсы
      txn = pm.currentTransaction();
      txn.begin();

      Iterator iterCity = cityExtent.iterator(); Extents.setImmediateRetrieve(iterCity, false);
      Iterator iterCraft = craftExtent.iterator(); Extents.setImmediateRetrieve(iterCraft, false);
      Flight flt;

      i = 1;
      int k1=1, k2;
      int k3=1, k4;
      String descr;
      while (i <= 2000 ) {
        flt = new Flight();
        k2 = d1.nextInt(49)+1;
        Extents.advance(iterCraft, k2-k1); k1 = k2;
        flt.crafttype = (CraftType)Extents.current(iterCraft);
        k4 = d1.nextInt(199)+1;
        Extents.advance(iterCity, k4-k3); k3 = k4;
        flt.startpoint = (City)Extents.current(iterCity);
        //flt.startpoint.flights.add(flt);
        while (k3 == k4) {k4 = d1.nextInt(199)+1;}
        Extents.advance(iterCity, k4-k3); k3 = k4;
        flt.endpoint = (City)Extents.current(iterCity);
        flt.description = flt.startpoint.name + "-" + flt.endpoint.name;
        //flt.items = new java.util.HashSet();
        pm.makePersistent(flt);
        i++;
      }
      cityExtent.close(iterCity);
      craftExtent.close(iterCraft);
      txn.commit();
      c1 = new GregorianCalendar();
      System.out.println(c1.getTime().toString());
      System.out.println("Flights: " + Integer.toString(i-1));
      System.out.println();


      // Персоны
      txn = pm.currentTransaction();
      txn.begin();

      i = 1;
      while (i <= 2000000 ) {
        pm.makePersistent(new Person(Integer.toString(i), "Name"+Integer.toString(i), "LastName"+Integer.toString(i)));
        i++;
        if (i % 10000 == 0) {Transactions.checkpoint( txn );}
      }
      txn.commit();
      c1 = new GregorianCalendar();
      System.out.println(c1.getTime().toString());
      System.out.println("Persons: " + Integer.toString(i-1));
      System.out.println();


      // Расписание и билеты
      Ticket tkt; Item itm;
      d1 = new Random(500);
      GregorianCalendar curr_day = new GregorianCalendar(2004, 10, 30);
      GregorianCalendar end_day = new GregorianCalendar(2005, 0, 2);
      i = 1; // счетчик рейсов (элементов расписания)
      int l = 1; // счетчик билетов (броней)

      while (!(curr_day.equals(end_day))) {
        txn = pm.currentTransaction();
        txn.setRetainValues(false);
        txn.begin();
        Iterator iterFlight = flightExtent.iterator(); Extents.setImmediateRetrieve(iterFlight, true);
        Iterator iterPerson = Extents.iterator(personExtent, "IDIndex"); Extents.setImmediateRetrieve(iterPerson, false);

        Extents.reset(iterFlight);
        while (iterFlight.hasNext()) {
          itm = new Item();
          itm.flight = (Flight)iterFlight.next();
          //itm.flight.items.add(itm);
          itm.day = 
               (curr_day.get(Calendar.DAY_OF_MONTH) <= 9 ?
                     "0" + Integer.toString(curr_day.get(Calendar.DAY_OF_MONTH)) :
                     Integer.toString(curr_day.get(Calendar.DAY_OF_MONTH)) ) + "." +
               (curr_day.get(Calendar.MONTH) <= 8 ?
                     "0" + Integer.toString(curr_day.get(Calendar.MONTH) + 1) :
                    Integer.toString(curr_day.get(Calendar.MONTH) + 1) ) + "." +
               Integer.toString(curr_day.get(Calendar.YEAR));
          itm.id = Integer.toString(i);
          itm.tickets1 = new HashSet();
          itm.tickets2 = new HashSet();
          pm.makePersistent(itm);

          // Билеты
          Iterator iterSeats1 = itm.flight.crafttype.seats1.iterator();
          Extents.reset(iterPerson);
          while (iterSeats1.hasNext()) {
            tkt = new Ticket();
            tkt.seat = (Seat)iterSeats1.next();
            if (!(d1.nextBoolean() & d1.nextBoolean())) {
              tkt.item = itm;
              k2 = d1.nextInt(1999999)+1;
              Extents.findKey(iterPerson, Integer.toString(k2));
              tkt.person = (Person)iterPerson.next();
              if (!(d1.nextBoolean() & d1.nextBoolean() & d1.nextBoolean())) {
                tkt.money_paid = d1.nextInt(500);
              }
              else {tkt.money_paid = 0;}
              itm.tickets1.add(tkt);
              l++;
            }
          }
          Iterator iterSeats2 = itm.flight.crafttype.seats2.iterator();
          while (iterSeats2.hasNext()) {
            tkt = new Ticket();
            tkt.seat = (Seat)iterSeats2.next();
            if (!(d1.nextBoolean() & d1.nextBoolean())) {
              tkt.item = itm;
              k2 = d1.nextInt(1999999)+1;
              Extents.findKey(iterPerson, Integer.toString(k2));
              tkt.person = (Person)iterPerson.next();
              if (!(d1.nextBoolean() & d1.nextBoolean() & d1.nextBoolean())) {
                tkt.money_paid = d1.nextInt(500);
              }
              else {tkt.money_paid = 0;}
              itm.tickets2.add(tkt);
              l++;
            }
          }
          i++;
          if (d1.nextBoolean()) {Extents.previous(iterFlight);}
          Transactions.checkpoint( txn );
          pm.evictAll();
        }
        curr_day.add(Calendar.DAY_OF_MONTH, 1);
        personExtent.closeAll();
        flightExtent.closeAll();
        txn.commit();
      }
      c1 = new GregorianCalendar();
      System.out.println(c1.getTime().toString());
      System.out.println("Items: " + Integer.toString(i-1));
      System.out.println("Tickets: " + Integer.toString(l-1));

      pm.close();  // closes the connection
  }

}

Файл JDO-метаданных (в т.ч. объявление индексов):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jdo SYSTEM "jdo.dtd">
<jdo>
   <extension vendor-name="FastObjects" key="database" value="avia_base"/>
   <extension vendor-name="FastObjects" key="schema" value="avia_dict"/>

<package name="avia.model">

<class name="Person">
	<extension vendor-name="FastObjects" key="index" value="IDIndex">
		<extension vendor-name="FastObjects" key="unique" value="true"/>
		<extension vendor-name="FastObjects" key="member" value="id"/>
	</extension>
</class>
<class name="CraftType" />

<class name="City">
	<extension vendor-name="FastObjects" key="index" value="NameIndex">
		<extension vendor-name="FastObjects" key="unique" value="true"/>
		<extension vendor-name="FastObjects" key="member" value="name"/>
	</extension>
</class>

<class name="Seat">
</class>

<class name="Flight">
	<extension vendor-name="FastObjects" key="index" value="PathIndex">
		<extension vendor-name="FastObjects" key="unique" value="false"/>
		<extension vendor-name="FastObjects" key="member" value="startpoint"/>
		<extension vendor-name="FastObjects" key="member" value="endpoint"/>
	</extension>
        <field name="items">
        	<collection element-type="avia.model.Item"/>
        </field>
</class>

<class name="Ticket">
	<extension vendor-name="FastObjects" key="index" value="ItemIndex">
		<extension vendor-name="FastObjects" key="unique" value="false"/>
		<extension vendor-name="FastObjects" key="member" value="item"/>
	</extension>
</class>

<class name="Item">
	<extension vendor-name="FastObjects" key="index" value="IDIndex">
		<extension vendor-name="FastObjects" key="unique" value="true"/>
		<extension vendor-name="FastObjects" key="member" value="id"/>
	</extension>
	<extension vendor-name="FastObjects" key="index" value="DayFlightIndex">
		<extension vendor-name="FastObjects" key="unique" value="false"/>
		<extension vendor-name="FastObjects" key="member" value="day"/>
                <extension vendor-name="FastObjects" key="member" value="flight"/>
	</extension>
</class>
</package>
</jdo>

Описания класов я уже давал выше.

Результаты сравнения в следующем посте ...

Еще раз уточняю. Пока речь идет о сравнении скорости при сохранении больших массивов случайных структурированных данных. Сравнение для выборки данных последует позднее.
13 апр 05, 20:27    [1466307]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
Итак, приведенный выше код сравнивался на скорость для Oracle 9i и FastObjects t7. Тестирование проводилось на рабочей станции Pentium 4, 512 Мб.

Я не придавал большого значения результатам, если они были близки друг к другу. Меня интересовала ситуация, когда одна система опережает другую значительно (в разы и на порядки).

Результаты сравнения

1. Первая часть теста (вплоть до генерации 2млн. Person включительно) на обоих системах отрабатывается приблизительно одинаково (10-15 мин.). Включение/отключение индексов влияет на быстродействие, но столь значительно, чтобы придавать этому большое значение.

2. Вторая часть теста, связанная с генерацией большого количества билетов (Ticket), выявила очень существенное ОТСТАВАНИЕ Oracle.

Подробнее по п.2

Приведенные в коде значения параметров приводят к генерации: 132126 - Item, 27241492 - Ticket.

Полное время отработки теста
для FastObjects - ~8-10 часов.
для Oracle - вечность (предположительно неделя).

Как и по п.1, включение/отключение индексов влияет на быстродействие, но столь значительно, чтобы придавать этому большое значение.

Причина медленной работы Oracle была найдена - значительные затраты на проверку ссылочной целостности. Отключение проверки соответствующих констрейнтов (это можно сделать через Ent. Manager Console) тут же приводит быстродействие Oracle в соответствие с быстродействием FastObjects.

Вывод

Приведенный пример служит хорошей иллюстрацией тех причин, по которым FastObjects t7 достаточно популярен в качестве встраиваемой СУБД различного телекоммуникационного оборудования (коммутаторы, оборудование абонентского выноса и т.п.), где быстрое сохранение больших объемов структурированных данных обычно и является основной функцией СУБД (а показатели производительности при использовании C++ наверняка будут еще выше, чем достигнутые в приведенном выше тесте на Java). Анализ же таких данных обычно проводится только после их импорта во внешние по отношению к оборудованию аналитические системы.

С уважением, Алексей Ровдо.
13 апр 05, 20:48    [1466339]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
vadiminfo
Member

Откуда: Обнинск
Сообщений: 4802
Alexey Rovdo

Вывод

Вывод просто достоин научной статьи, а метод его пролучения следует предолжить в качестве образца в палату весов и времени.
И где тока все эти изобритатели тестов и правил их проведения.
Не хватет мелочей - трассировки сессии, чтобы понять чем собственно заставили занbматься Оракл. Скока времени и чего он ждал (может Джаву)
Не плохо бы понять какое время потратила Джава с таким кодом.
Особенно производит впечатление загрузка
PreparedStatement pstmt3 =
conn.prepareStatement("SELECT MIN(Seat.id) seat_id_start, MAX(Seat.id)
seat_id_end FROM Seat INNER JOIN Flight ON Flight.crafttype_id =
Seat.crafttype_id WHERE Flight.id = ?");
2000000 - раз, возможно в цикле.
Не известно, о состоянии ресурсов самого сервера - мож Джава машина там отнимала 50% процессорного времени.
Поскольку не был приглашен опытный Ораклист, можно предположить, что таким способом можно прийти к выводу, что один Оракл быстрее другого Оракла.
13 апр 05, 22:40    [1466461]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Su  [new]
c127
Guest
2 Alexey Rovdo

>Вывод

Приведенный пример служит хорошей иллюстрацией тех причин, по которым FastObjects t7 достаточно популярен в качестве встраиваемой СУБД различного телекоммуникационного оборудования (коммутаторы, оборудование абонентского выноса и т.п.), где быстрое сохранение больших объемов структурированных данных обычно и является основной функцией СУБД (а показатели производительности при использовании C++ наверняка будут еще выше, чем достигнутые в приведенном выше тесте на Java). Анализ же таких данных обычно проводится только после их импорта во внешние по отношению к оборудованию аналитические системы.


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

c127, 12 апр 05, 04:33>Еще очень сильно могут влиять настройки сервера, но это нужно говорить с ДБА. Выложите свои настройки, может кто-нибудь подскажет что подправить.
14 апр 05, 02:15    [1466595]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
vadiminfo
Alexey Rovdo

Вывод

Вывод просто достоин научной статьи, а метод его пролучения следует предолжить в качестве образца в палату весов и времени.
И где тока все эти изобритатели тестов и правил их проведения.
Не хватет мелочей - трассировки сессии, чтобы понять чем собственно заставили занbматься Оракл. Скока времени и чего он ждал (может Джаву)
Не плохо бы понять какое время потратила Джава с таким кодом.
Особенно производит впечатление загрузка
PreparedStatement pstmt3 =
conn.prepareStatement("SELECT MIN(Seat.id) seat_id_start, MAX(Seat.id)
seat_id_end FROM Seat INNER JOIN Flight ON Flight.crafttype_id =
Seat.crafttype_id WHERE Flight.id = ?");
2000000 - раз, возможно в цикле.
Не известно, о состоянии ресурсов самого сервера - мож Джава машина там отнимала 50% процессорного времени.
Поскольку не был приглашен опытный Ораклист, можно предположить, что таким способом можно прийти к выводу, что один Оракл быстрее другого Оракла.


Ключевой момент здесь вовсе не в Java и ресурсах сервера. А в том, что при деактивации констрейнтов в таблице Ticket скорость отработки теста увеличивается на 70-90%. Любые ухищрения с кодом (переход на PL/SQL, переписывание запросов и т.п.) при таком раскладе не смогут увеличить эту скорость более чем на 10-30%. И этот вывод совершенно очевиден для того, кто может сложить 30+70 (10+90).

Единственное с чем я могу согласиться - это то, что изменение настроек конфигурации Oracle теоретически может ускорить именно проверку ссылочной целостности. Но для достижения сравнимых с FastObjects показателей ее нужно ускорить в разы. Какие параметры конфигурации за это отвечают? Готов провести экперименты.
14 апр 05, 10:28    [1467113]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Su  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
Еще раз объясняю.

Есть некий тестовый код. При отключенной проверке целостности ссылок он выполняется за 8-10 часов. При включении проверки - вечность.

Допустим мы улучшили этот код кардинально и теперь наш правильный и фантастически оптимальный код при отключенной проверке целостности ссылок выполняется за 0 часов. Тогда, если мы ничего не предпринимали именно для ускорения проверки ссылочной целостности (а это вероятно возможно только изменением настроек конфигурации СУБД и железа), то такой супер-пупер оптимизированный код после включения проверки будет выполняться: вечность - 10 часов = вечность.

Весь код выложен в этом форуме. Если кому-то удастся загнать в Oracle тестовые данные без отключения индексов и констреинтов быстрее чем за 2 дня - милости прошу - продолжим обсуждение. А пока только скрежет зубами и оскорбления (видимо по существу и нечего сказать).
14 апр 05, 10:37    [1467175]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
aq_tm_processes = 1
background_dump_dest = C:\oracle\admin\AVIATEST\bdump
compatible = 9.2.0.0.0
control_files = ('D:\oradata\AVIATEST\CONTROL01.CTL', 'D:\oradata\AVIATEST\CONTROL02.CTL', 'D:\oradata\AVIATEST\CONTROL03.CTL')
core_dump_dest = C:\oracle\admin\AVIATEST\cdump
db_block_size = 8192
db_cache_size = 16777216
db_domain = ''
db_file_multiblock_read_count = 32
db_name = AVIATEST
dispatchers = '(PROTOCOL=TCP) (SERVICE=AVIATESTXDB)'
fast_start_mttr_target = 300
hash_area_size = 1048576
hash_join_enabled = TRUE
instance_name = AVIATEST
java_pool_size = 33554432
job_queue_processes = 10
large_pool_size = 8388608
log_archive_dest_1 = 'LOCATION=C:\oracle\ora92\RDBMS'
open_cursors = 300
pga_aggregate_target = 33554432
processes = 150
query_rewrite_enabled = TRUE
remote_login_passwordfile = EXCLUSIVE
shared_pool_size = 50331648
sort_area_size = 1048576
star_transformation_enabled = TRUE
timed_statistics = TRUE
undo_management = AUTO
undo_retention = 0
undo_tablespace = UNDOTBS1
user_dump_dest = C:\oracle\admin\AVIATEST\udump

14 апр 05, 10:46    [1467223]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
Не будете ли так бобры ?

select table_name, constraint_name,
       cname1 || nvl2(cname2,','||cname2,null) ||
       nvl2(cname3,','||cname3,null) || nvl2(cname4,','||cname4,null) ||
       nvl2(cname5,','||cname5,null) || nvl2(cname6,','||cname6,null) ||
       nvl2(cname7,','||cname7,null) || nvl2(cname8,','||cname8,null) 
            columns
  from ( select b.table_name, 
                b.constraint_name,
                max(decode( position, 1, column_name, null )) cname1,
                max(decode( position, 2, column_name, null )) cname2,
                max(decode( position, 3, column_name, null )) cname3,
                max(decode( position, 4, column_name, null )) cname4,
                max(decode( position, 5, column_name, null )) cname5,
                max(decode( position, 6, column_name, null )) cname6,
                max(decode( position, 7, column_name, null )) cname7,
                max(decode( position, 8, column_name, null )) cname8,
                count(*) col_cnt
           from (select substr(table_name,1,30) table_name, 
                        substr(constraint_name,1,30) constraint_name,
                        substr(column_name,1,30) column_name,
                        position
                   from user_cons_columns ) a, 
                user_constraints b
          where a.constraint_name = b.constraint_name
            and b.constraint_type = 'R'
          group by b.table_name, b.constraint_name
       ) cons
 where col_cnt > ALL 
         ( select count(*)
             from user_ind_columns i
            where i.table_name = cons.table_name
              and i.column_name in (cname1, cname2, cname3, cname4, 
                                    cname5, cname6, cname7, cname8 )
              and i.column_position <= cons.col_cnt
            group by i.index_name
         )
/


???

При поднятых констрейнтах, разумеется
14 апр 05, 10:58    [1467272]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
Снимаю вопрос, нашел Ваши индексы
14 апр 05, 11:01    [1467288]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
Забавный код :) В одном месте параметризуете запросы в другом нет
14 апр 05, 11:07    [1467321]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
tygra
Member

Откуда: Тверь (Иркутск, Край)
Сообщений: 9997
Мдаааа, таки удалось сравнить скорость работы Java-кода с вкраплениями sql.
Оказалось, что что-то, написанное на Java, с Ораклом работает хуже, чем с Версантом. Потому что программист не смог написать лучше под Оракл.

Есть предложения:
1. Привести реальный пример, где бы нужно было добавить 2 000 000 билетов друг за другом и как можно быстрее.
2. Привести хоть какой-нибудь пример, где бы нужно было вставлять данные с такой скоростью и при похожей структуре
3. Если хочется действительно сравнить скорость вставки, то выкладывайте эти данные в полоские файлы - именно результирующие данные - и давайте их просто зальем в БД. Вот тут и посмотрим, чего и как. Иначе сравнивается неизвестно что - толи скорость Java-кода, толи скорость двух миллионов селектов из таблицы (селектов, не инсертов!)...

В общем, лажа получилась, полнейшая!

-- Tygra's --
14 апр 05, 11:13    [1467354]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
По поводу предложений, а не пустых комметариев. Забываем про dataset-ы, гененрим параметризованный insert, разбираем его, вставляем данные, меряем скорость. Должно помочь :)
14 апр 05, 11:14    [1467357]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
Gluk (Kazan)
Забавный код :) В одном месте параметризуете запросы в другом нет


А я поначалу их везде не параметризовал. Конечно быстродействие страдает. В основном это сразу видно в TasK Manager - Oracle ест процессорный ресурс (парсит запросы). Но в целом быстродействие страдает, хоть и сильно, но не в разы.

А вообще, вплоть до момента окончания генерации 2 млн. Person включительно, существенных проблем в быстродействии не наблюдается. И Oracle и FastObjects делают это за 10-15 минут, так что в целом на результат теста этот код практически никакого влияния не оказывает - потому и не переписывал его.
14 апр 05, 11:14    [1467358]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
При работе из многих сессий в разы. К тому-же хорошо было-бы избавиться и от мягких разборов (для чистоты эксперимента).
14 апр 05, 11:15    [1467365]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Alexey Rovdo
Member

Откуда: Москва
Сообщений: 913
tygra

3. Если хочется действительно сравнить скорость вставки, то выкладывайте эти данные в полоские файлы - именно результирующие данные - и давайте их просто зальем в БД. Вот тут и посмотрим, чего и как.


Давайте, но с одним условием - индексы и констрейнты должны быть включены. Т.е. СУБД должна обеспречивать проверку целостности ссылок и перестроение индексов по мере поступления новых данных.

Да, и перестаньте тыкать в 2-х милионную таблицу Person. С ней никаких проблем и вопросов. Замедление имеет место только тогда, когда идет проверка ссылочной целостности (27 млн. записей в таблице Ticket).
14 апр 05, 11:18    [1467380]     Ответить | Цитировать Сообщить модератору
 Re: Объектные СУБД от Versant Corporation (FastObjects .NET, FastObjects t7, Developer Suite)  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
Вообще, при массовых заливках констрэйнты и лишние индексы обычно отключают. Oracle силен не быстрой всавкой. А если уж приспичело что-то навставлять, есть SQLLoader с Direct модом.
14 апр 05, 11:18    [1467381]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 21 22 23 24 25 [26] 27 28 29 30 .. 34   вперед  Ctrl
Все форумы / Сравнение СУБД Ответить