Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate vs JDBC. Производительность. 
:(
    Опции темы
unkis
  Дата 7.6.2007, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 802
Регистрация: 8.9.2004

Репутация: нет
Всего: 1



Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC.
Вот я и подумал может, я не правильно использую Hibernate.

Я написал пример, который кладёт в три таблицы 100,1000 объектов(делает 300,3000 insert) и вот результаты:
структура таблиц:
Timestamp<------->time_request<------>Request

Тестовая конфиг.
JDK 1.6
HSQL
Vindows Vista

100 объектов
Hiberane  631ms
JDBC         7ms
   
1000 объектов
Hiberane  5425ms
JDBC         56ms

Как видите сами, Hibernate во много раз медленнее.

Вопрос можно ли под шаманить и добиться, более приемлемых результатов у hibernate.

Тестовый проект(размер ~6Mb) можно скачать >>>здесь<<<, он содержит в себе всё необходимое, 
только запустить и всё.
Запуск BD и GUI к ней же, осуществляется через два *.bat файла лежащих в папке lib.

Вот так я сохраняю.
Код

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.ejb.EntityManagerFactoryImpl;

import test.Request;
import test.RequestTime;
import test.TimeStamp;


public class MainTest {
    private EntityManagerFactory emf;

    private Session entityManager;

    private Transaction tx2;

    private int insert = 1000;

    public MainTest() {

        emf = Persistence.createEntityManagerFactory("test");
        entityManager = (Session) emf.createEntityManager().getDelegate();
        tx2 = entityManager.getTransaction();
        start();
//        saveWithNativeSQL();

    }

    private void start() {

        tx2.begin();

        ArrayList<RequestTime> liste = new ArrayList<RequestTime>();
        for (int i = 0; i < insert; i++) {

            TimeStamp timeStamp = new TimeStamp();
            timeStamp.setDay((byte) (6 + i));
            timeStamp.setHour((byte) (5 + i));
            timeStamp.setMonth((byte) (7 - i));

            Request request = new Request("XMLCON", "198.56.3.255", "wap");

            RequestTime newLink = new RequestTime(666, timeStamp, request);

            liste.add(newLink);

            //        List<RequestTime> criteria = entityManager.createCriteria(RequestTime.class).
            //        add( Restrictions.eq("request", request)).
            //        add(Restrictions.eq("timeStamp", timeStamp)).list();

        }

        long start = System.currentTimeMillis();
        for (RequestTime time : liste) {
            entityManager.save(time);
        }

        tx2.commit();
        entityManager.close();
        System.out.println("Done.\tExecuted time: "
                + (System.currentTimeMillis() - start));

    }

    private void saveWithNativeSQL() {
        try {
            Class.forName("org.hsqldb.jdbcDriver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            int[] updateCounts = null;
            java.sql.Connection con = DriverManager.getConnection(
                    "jdbc:hsqldb:hsql://localhost/test", "sa","");
            con.setAutoCommit(false);
            long start = System.currentTimeMillis();
            Statement s = con.createStatement();
            for (int i = 1; i < insert; i++) {

                s.addBatch("INSERT INTO Request VALUES (" + i
                        + ",'aaa','aaa','aaa')");
                s.addBatch("INSERT INTO TimeStamp VALUES (" + i + ",5,1,1,1)");
                s.addBatch("INSERT INTO time_request VALUES (" + i + ",5," + i
                        + "," + i + ")");
            }
            updateCounts = s.executeBatch();
            con.commit();
            System.out.println("Done.\tExecuted time: "
                    + (System.currentTimeMillis() - start));
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new MainTest();

    }

}


вот так выглядит мой конфиг. файл.
Код

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <persistence-unit name="test">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>test.TimeStamp</class>
        <class>test.RequestTime</class>
        <class>test.Request</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/test" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
        <!--    <property name="hibernate.cache.provider_class"
                value="org.hibernate.cache.EhCacheProvider" />  -->
            <property name="hibernate.connection.username" value="sa" />
        <!--    <property name="hibernate.connection.password" value="" /> 
            <property name="hibernate.jdbc.batch_size" value="50" /> -->
            <property name="hibernate.cache.use_second_level_cache" 
                value="false" /> 
            <property name="hibernate.hbm2ddl.auto" value="create" />
        <!--    <property name="hibernate.show_sql" value="true" /> 
            <property name="hibernate.max_fetch_depth" value="3" /> -->
        </properties>
    </persistence-unit>
</persistence>


вот так выглядят мои маппинги.
Код

/**
 * (Start,[Via1,Via2,..Vian], Ziel)
 */
package test;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.IndexColumn;

/**
 * @author Unkis
 *
 */
@Entity
@Table(name = "Request")
public class Request implements Serializable {

    private long id;

    private Collection timeStamps;

    private String type;

    private String virtServer;

    private String info;

    public Request() {

    }

    public Request(Collection timeStamps, String type, String virtServer,
            String info) {
        super();
        this.timeStamps = timeStamps;
        this.type = type;
        this.virtServer = virtServer;
        this.info = info;
    }

    public Request(String type, String virtServer, String info) {
        super();
        this.type = type;
        this.virtServer = virtServer;
        this.info = info;
    }

    @Id
    @Column(name = "request_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getVirtServer() {
        return virtServer;
    }

    public void setVirtServer(String virtServer) {
        this.virtServer = virtServer;
    }

    @ManyToMany(targetEntity = TimeStamp.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "time_request", joinColumns = @JoinColumn(name = "request_id"), inverseJoinColumns = @JoinColumn(name = "time_id"))
    public Collection getTimeStamps() {
        return timeStamps;
    }

    public void setTimeStamps(Collection locations) {
        this.timeStamps = locations;
    }

}



Код

package test;

import java.io.Serializable;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "time_request")
public class RequestTime implements Serializable {

    private long id;

    private Request request;

    private TimeStamp timeStamp;

    private int number;

    public RequestTime() {
        super();
        // TODO Auto-generated constructor stub
    }

    public RequestTime(int number, TimeStamp timeStamps, Request request) {
        super();
        this.request = request;
        this.timeStamp = timeStamps;
        this.number = number;
    }

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Basic
    @Column(nullable = false)
    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "time_id", nullable = false, updatable = false)
    public TimeStamp getTimeStamp() {
        return timeStamp;
    }

    public void setTimeStamp(TimeStamp timeStamp) {
        this.timeStamp = timeStamp;
    }

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "request_id", nullable = false, updatable = false)
    public Request getRequest() {
        return request;
    }

    public void setRequest(Request request) {
        this.request = request;
    }

}



Код

package test;

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;

@Entity
public class TimeStamp implements Serializable {

    //    private Long id;

    /**
     * Id of location
     */
    private Long time_id;

    private Collection resuests;

    private byte hour;

    private byte day;

    private byte month;

    private short year;

    public TimeStamp() {
        super();
        // TODO Auto-generated constructor stub
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "location_id")
    public Long getTime_id() {
        return time_id;
    }

    public void setTime_id(Long location_id) {
        this.time_id = location_id;
    }

    public TimeStamp(Collection resuests, byte hour, byte day, byte month,
            short year) {
        super();
        this.resuests = resuests;
        this.hour = hour;
        this.day = day;
        this.month = month;
        this.year = year;
    }

    public TimeStamp(byte hour, byte day, byte month, short year) {
        super();
        this.hour = hour;
        this.day = day;
        this.month = month;
        this.year = year;
    }

    public byte getDay() {
        return day;
    }

    public void setDay(byte day) {
        this.day = day;
    }

    public byte getHour() {
        return hour;
    }

    public void setHour(byte hour) {
        this.hour = hour;
    }

    public byte getMonth() {
        return month;
    }

    public void setMonth(byte month) {
        this.month = month;
    }

    public short getYear() {
        return year;
    }

    public void setYear(short year) {
        this.year = year;
    }

    @ManyToMany(targetEntity = Request.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "time_request", joinColumns = @JoinColumn(name = "time_id"), inverseJoinColumns = @JoinColumn(name = "request_id"))
    public Collection getResuests() {
        return resuests;
    }

    public void setResuests(Collection resuests) {
        this.resuests = resuests;
    }

}



 






--------------------
www.unkis.com
PM MAIL WWW   Вверх
tux
Дата 8.6.2007, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



Затраты на работу Hibernate в общем времени работы с данными сами товарищи, разрабатывающие Hibernate оценивают в 10%. Я с ними в целом солидарен. Эксперимент у тебя не чистый - Hibernate не умеет делать addBatch(). Попробуй каждый запрос выполнять в отдельном стейтменте (Hibernate так и делает), тогда должны получиться сопоставимые результаты.
PM MAIL Skype GTalk Jabber YIM   Вверх
Tony
Дата 8.6.2007, 08:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: 6
Всего: 12



V 3-5 raza medlenne 4em JDBC. V nete bilo horoshee sravnenie Hibernate/JDBC/IBATIS. Pravada ssilku zabyl.  smile . Tak tam HSQL byl voobshe v zh.....   smile 


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
tux
Дата 8.6.2007, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



Цитата(Tony @  8.6.2007,  08:20 Найти цитируемый пост)
Tak tam HSQL byl voobshe v zh.....   smile  

Причем тут HSQL? Сравнивали Hibernate, iBatis, JDBC с HSQL?
PM MAIL Skype GTalk Jabber YIM   Вверх
unkis
  Дата 8.6.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 802
Регистрация: 8.9.2004

Репутация: нет
Всего: 1



нет, я всё понимаю, что hibernate должен быть чуть-чуть медленнее, ведь он сам основан на JDBC, меня больше интересует, как из него выжать максимальную скорость, как максимально ускорить результат?


--------------------
www.unkis.com
PM MAIL WWW   Вверх
Tony
Дата 8.6.2007, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: 6
Всего: 12



Cach nado ispolozovat': sudi
I vot eshjo.  hibernate manual


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
unkis
Дата 8.6.2007, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 802
Регистрация: 8.9.2004

Репутация: нет
Всего: 1



Цитата(Tony @  8.6.2007,  10:02 Найти цитируемый пост)
Cach nado ispolozovat': sudi

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



--------------------
www.unkis.com
PM MAIL WWW   Вверх
tux
Дата 8.6.2007, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



Цитата(unkis @  8.6.2007,  10:25 Найти цитируемый пост)
нет, я всё понимаю, что hibernate должен быть чуть-чуть медленнее, ведь он сам основан на JDBC, меня больше интересует, как из него выжать максимальную скорость, как максимально ускорить результат? 

У тебя такой эффект из-за того, что в JDBC используются методы addBatch() и executeBatch(). По этому поводу два замечания. 
  • Этот метод - optional, в некоторых JDBC-драйверах его просто может не быть, поэтому Hibernate в принципе не может его использовать так как ему со многими СУБД работать
  • Метод executeBatch() в Hypersonic скорее всего реализован таким образом, что драйвер сначала накапливает команды в памяти когда вызываются addBatch(),  а потом посылает их всей пачкой, что гораздо быстрее, чем выполнять всю тысячу команд по отдельности. Думаю для других СУБД эффект может быть другим.
В общем резюме такое. Для конкретной связки Hibernate+Hypersonic производительности executeBatch() добиться не удастся по той причине, что Hibernate executeBatch() выполнить не сможет. Для других СУБД этого метода просто может не быть, а возможно и не будет такой разницы в производительности. Ускорить работу вставки, обновления и удаления в Hibernate вряд ли удастся, другое дело выборки, там огромный простор для деятельности.
PM MAIL Skype GTalk Jabber YIM   Вверх
Tony
Дата 8.6.2007, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: 6
Всего: 12



Цитата(unkis @ 8.6.2007,  12:25)
Цитата(Tony @  8.6.2007,  10:02 Найти цитируемый пост)
Cach nado ispolozovat': sudi

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

Ja dal obshij sovet.  Kod ne smotrel.


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0907 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.