Привет всем, у меня такая проблема, я заметил что при использовании 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.
Здравствуйте, unkis, Вы писали:
U>Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC. U>Вот я и подумал может, я не правильно использую Hibernate.
U>>Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC. U>>Вот я и подумал может, я не правильно использую Hibernate.
B>Как на счет того чтобы начать с небольшого RTFM?
читал я это, у меня отключён второй уровень cash, и сохраняю пока я не так много объектов(нет у меня проблемы с OutOfMemoryException ), поэтому мне не надо делать
session.flush();
session.clear();
вы бы с начало посмотрели, что у меня в конфиг. файле стоит, а потом отсылали меня к документации.
единственное что я не понял что это такое hibernate.jdbc.batch_size 20
Здравствуйте, unkis, Вы писали:
U>при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC.
для закачки данных с клиента стоит пользоваться batch-загрузкой,
а в идеале, если конкретная СУБД имеет нативные тулзы для загрузки данных, а серверный компьютер предоставляет файловый и управленчекский доступ (ssh в идеале или ftp+telnet), то можно генерировать текстовые файлы для загрузки, передавать их на сервер, там уже вызывать нужный тул. я это успешно делал для oracle, у него есть sqlldr, возможно, другие "хорошие" СУБД тоже что-то аналогичное предоставляют
C0s>для закачки данных с клиента стоит пользоваться batch-загрузкой,
Это что за загрузка такая? и как её пользоваться?
C0s>а в идеале, если конкретная СУБД имеет нативные тулзы для загрузки данных, а серверный компьютер предоставляет файловый и управленчекский доступ (ssh в идеале или ftp+telnet), то можно генерировать текстовые файлы для загрузки, передавать их на сервер, там уже вызывать нужный тул. я это успешно делал для oracle, у него есть sqlldr, возможно, другие "хорошие" СУБД тоже что-то аналогичное предоставляют
это всё хорошо, но потом надо будет не только вставлять, а перед этим ещё и делать выборку, так что текстовые файлы не подходят, хотя если hibernate в место comit мог бы сохранять в текстовые файлы, возможно это было бы приемлемо.
Здравствуйте, unkis, Вы писали:
C0s>>для закачки данных с клиента стоит пользоваться batch-загрузкой,
U>Это что за загрузка такая? и как её пользоваться?
там, кажется, выше Blazkowicz дал ссылку
C0s>>а в идеале, если конкретная СУБД имеет нативные тулзы для загрузки данных, а серверный компьютер предоставляет файловый и управленчекский доступ (ssh в идеале или ftp+telnet), то можно генерировать текстовые файлы для загрузки, передавать их на сервер, там уже вызывать нужный тул. я это успешно делал для oracle, у него есть sqlldr, возможно, другие "хорошие" СУБД тоже что-то аналогичное предоставляют
U>это всё хорошо, но потом надо будет не только вставлять, а перед этим ещё и делать выборку, так что текстовые файлы не подходят, хотя если hibernate в место comit мог бы сохранять в текстовые файлы, возможно это было бы приемлемо.
это я предложил альтернативный путь (без hibernate/jdbc)... если идти таким путем, то данные обычно закачиваются в отдельные таблицы, а потом вызываются хранимые процеуры, которые уже и выборки нужные делают и данные перекладывают куда надо и как надо и т.п.
гибридный вариант, кстати, тоже возможен — загрузить данные описанным способом в те таблицы, которые тоже замаплены на hibernate, а потом работать в терминах select, insert from select и других массовых операций, доступных в hibernate 3.x
Здравствуйте, unkis, Вы писали:
U>единственное что я не понял что это такое hibernate.jdbc.batch_size 20
In this chapter we'll show you how to avoid this problem. First, however, if you are doing batch processing, it is absolutely critical that you enable the use of JDBC batching, if you intend to achieve reasonable performance. Set the JDBC batch size to a reasonable number (say, 10-50):
Здравствуйте, C0s, Вы писали:
U>>единственное что я не понял что это такое hibernate.jdbc.batch_size 20 U>>За что этот размер отвечает?
C0s>емнип, этот параметр отвечает за порционность чтения данных из зависимых коллекций, которые загружаются ленивым образом
сорри, попутало меня с fetch_size .... Blazkowicz правильно написал
B>In this chapter we'll show you how to avoid this problem. First, however, if you are doing batch processing, it is absolutely critical that you enable the use of JDBC batching, if you intend to achieve reasonable performance. Set the JDBC batch size to a reasonable number (say, 10-50):
Вы меня извините но я всё равно не понял что это такое, у меня как раз стоит hibernate.jdbc.batch_size 50. могу поставить меньше только я не понимаю на что это влияет, что выставляет это значение.
Подскажите что подправить или объясните по подробней, ну не понимаю я, что это такое.
Какое-то у Вас сравнение теплого с мягким. Чего Вы сравниваете Hibernate с batch загрузкой данных?
Вы не могли бы объяснить что означает batch загрузка данных.
Здравствуйте, unkis, Вы писали:
U>Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC. U>Вот я и подумал может, я не правильно использую Hibernate.
Ребята я бюсь над этой проблемой уже почти ниделю, у меня ничего не выходит, Batch processing мне не подходит из-за скорости, да он позволяет вставлять 1000000 обеъектов при этом не получив ошибку о переполнении памяти, но делает он это гараздо медленнее чем через JDBC.
Я так понимаю что предназначение Batch processing, как раз устранение ошибки OutOfMemoryException, с чем он прикрасно справлдяется, но ни как для скоростной вставки.
Я никак не пойму, неужели нет возможности в Hibernate записывать в базу обекты, хотя бы приблезительно так же быстро, как это можно сделать через JDBC?
Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.
Здравствуйте, unkis, Вы писали:
U>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.
Забиваешь гвозди микроскопом. ORM хорош в работе с деревьями объектов. При работе с большими объемами плоских данных в нем смысла собого нет. Напиши этот кусок на JDBC и не мучайся.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, unkis, Вы писали:
U>>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом. B>Забиваешь гвозди микроскопом. ORM хорош в работе с деревьями объектов. При работе с большими объемами плоских данных в нем смысла собого нет. Напиши этот кусок на JDBC и не мучайся.
это я сейчас привёл приер с тупым инсертом, а вдяльнейшем мне надо будет перед каждым инсёртом проверять существует ли такой объект или нет, тоесть делать выборку, и если существует то тогда один параметр этого объекта увеличить на один и update. и вот здесь hibernate был бы как раз кстати. так как он делал бы всего один update за всю транзакцию(мне так кажется что hibernate так и делает).
вот я тут ещё что хочу попробывать, если не поможет то буду писать всё без hibernate. 13.4. DML-style operations
но что-то у меня пока не получается сделать правильную вставку, я делаю так
Query q =entityManager.createQuery("insert into TimeStamp (hour,day,month,year) (4,1,1,2001) ");
int updatedItems = q.executeUpdate();
а он мне пишет
16:32:15,548 DEBUG JDBCContext:210 - after transaction begin
16:32:15,548 DEBUG QueryPlanCache:70 - unable to locate HQL query plan in cache; generating (insert into TimeStamp (hour,day,month,year) (4,1,1,2001) )
16:32:15,579 DEBUG QueryTranslatorImpl:246 - parse() - HQL: insert into TimeStamp (hour,day,month,year) (4,1,1,2001)
16:32:15,579 ERROR PARSER:33 - line 1:45: unexpected token: (
16:32:15,579 DEBUG ErrorCounter:28 - line 1:45: unexpected token: (
line 1:45: unexpected token: (
at org.hibernate.hql.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1122)
at org.hibernate.hql.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:702)
at org.hibernate.hql.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:296)
at org.hibernate.hql.antlr.HqlBaseParser.insertStatement(HqlBaseParser.java:328)
at org.hibernate.hql.antlr.HqlBaseParser.statement(HqlBaseParser.java:165)
at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:248)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
at MainTest.start(MainTest.java:71)
at MainTest.<init>(MainTest.java:40)
at MainTest.main(MainTest.java:124)
16:32:15,579 DEBUG AST:266 - --- HQL AST ---
\-[INSERT] 'insert'
+-[INTO] 'into'
| +-[IDENT] 'TimeStamp'
| \-[RANGE] 'column-spec'
| +-[IDENT] 'hour'
| +-[IDENT] 'day'
| +-[IDENT] 'month'
| \-[IDENT] 'year'
\-[QUERY] 'query'
Exception in thread "main" org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 45 [insert into TimeStamp (hour,day,month,year) (4,1,1,2001) ]
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:31)
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:24)
at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:59)
at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:258)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
at MainTest.start(MainTest.java:71)
at MainTest.<init>(MainTest.java:40)
at MainTest.main(MainTest.java:124)
как должен правельно выглядеть insert в таком случаи?
Здравствуйте, unkis, Вы писали:
U>это я сейчас привёл приер с тупым инсертом, а вдяльнейшем мне надо будет перед каждым инсёртом проверять существует ли такой объект или нет, тоесть делать выборку, и если существует то тогда один параметр этого объекта увеличить на один и update. и вот здесь hibernate был бы как раз кстати. так как он делал бы всего один update за всю транзакцию(мне так кажется что hibernate так и делает).
Такие вещи вообше надо в базе писать всякими процедурами и триггерами.
U>
U>а он мне пишет U>16:32:15,579 DEBUG ErrorCounter:28 — line 1:45: unexpected token: ( U>как должен правельно выглядеть insert в таком случаи?
Все верно пишет.
Здравствуйте, unkis, Вы писали:
U>вот я тут ещё что хочу попробывать, если не поможет то буду писать всё без hibernate.
А что за крайности всё или ничего. Напиши критические участки на том же JDBC и не мучайся. Хибер он же в основном проиводительность программера увеличивает а не системы.
B>>Вот ещё есть что почитать.
U>Ребята я бюсь над этой проблемой уже почти ниделю, у меня ничего не выходит, Batch processing мне не подходит из-за скорости, да он позволяет вставлять 1000000 обеъектов при этом не получив ошибку о переполнении памяти, но делает он это гараздо медленнее чем через JDBC.
У меня была абсолютно та же проблема с JPA. В рамках одной транзакции не очищается кэш сессии, т.е. надо разбивать на транзакции, чтобы исключение не бросалось. Hibernate же не знает, что объект вам не понадобится больше.
U>Я так понимаю что предназначение Batch processing, как раз устранение ошибки OutOfMemoryException, с чем он прикрасно справлдяется, но ни как для скоростной вставки.
batch updates, в JDBC во всяком случае, нужны чтобы не создавать каждый раз отдельный запрос, а передавать данные пачками.
U>Я никак не пойму, неужели нет возможности в Hibernate записывать в базу обекты, хотя бы приблезительно так же быстро, как это можно сделать через JDBC?
Используйте загрузку данных из файла скриптом, как мне посоветовали. Самый быстрый способ.
U>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.
Модель использования ORM совсем другая. Глупо использовать ORM, скажем, для Time-Series.
B>Такие вещи вообше надо в базе писать всякими процедурами и триггерами.
Я об этом думал, но останавливает меня две вещи.
1) писать тригер или процедуру, это привязать себя к конкретной базе данных. что конечно не критично, но не хотелось бы.
2) как будет вести себя тригер, если он не успеет сделать выборку или посчитать что-то, как к ниму приходит уже новый инсёрт, если он их будет обрабатывать по очереди, то тогда ничего страшного, но если каждый отдельно то получится каша, на чей совести остаётся проблема синхронизации?
B>>Такие вещи вообше надо в базе писать всякими процедурами и триггерами.
U>Я об этом думал, но останавливает меня две вещи. U>1) писать тригер или процедуру, это привязать себя к конкретной базе данных. что конечно не критично, но не хотелось бы. U>2) как будет вести себя тригер, если он не успеет сделать выборку или посчитать что-то, как к ниму приходит уже новый инсёрт, если он их будет обрабатывать по очереди, то тогда ничего страшного, но если каждый отдельно то получится каша, на чей совести остаётся проблема синхронизации?
да и в каком случаи использовать триггеры, а в каком хранимые процедуры?