Здравствуйте, unkis, Вы писали:
U>А можно немножко поп подробней про MD5, я что-то не понял почему они ьогут быть одинаковыми?
Тю, это же логика.
1) Множество всех строк больше чем множество всех их MD5 hash кодов. Это надо объяснять почему?
2) Каждой строке соответствует один MD5 hash код.
Вот и получается логичный вывод что есть такие строки которым соответствует одит и тот же MD5 hash код.
Здравствуйте, unkis, Вы писали:
U>Ребята я бюсь над этой проблемой уже почти ниделю, у меня ничего не выходит, Batch processing мне не подходит из-за скорости, да он позволяет вставлять 1000000 обеъектов при этом не получив ошибку о переполнении памяти, но делает он это гараздо медленнее чем через JDBC. U>Я так понимаю что предназначение Batch processing, как раз устранение ошибки OutOfMemoryException, с чем он прикрасно справлдяется, но ни как для скоростной вставки.
U>Я никак не пойму, неужели нет возможности в Hibernate записывать в базу обекты, хотя бы приблезительно так же быстро, как это можно сделать через JDBC?
U>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.
Не поленился и проделал аналогичный тест. 20000 записей, СУБД — Oracle:
Что могу посоветовать (у меня тоже не сразу быстро заработало):
— проверить, как hibernate генерит ключи (я поставил increment);
— выключить лог. Несмотря на batch-операцию, лог hibernate пишет для каждого объекта;
— проверить, что hibernate.jdbc.batch_size включен, а то в первом письме он был закоменчен
U> <!-- <property name="hibernate.connection.password" value="" /> U> <property name="hibernate.jdbc.batch_size" value="50" /> -->
Здравствуйте, 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):
Здравствуйте, unkis, Вы писали:
U>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.
Забиваешь гвозди микроскопом. ORM хорош в работе с деревьями объектов. При работе с большими объемами плоских данных в нем смысла собого нет. Напиши этот кусок на JDBC и не мучайся.
Здравствуйте, unkis, Вы писали:
U>вот я тут ещё что хочу попробывать, если не поможет то буду писать всё без hibernate.
А что за крайности всё или ничего. Напиши критические участки на том же JDBC и не мучайся. Хибер он же в основном проиводительность программера увеличивает а не системы.
ты самое главное не написал — какая именно база у тебя. кстати, сверять ТОЛЬКО MD5 — неверно т.к. две строки могут иметь одинаковый hash и разные данные. нужно сверять и то и другое, сначала MD5 (а лучше SHA-1), конечно.
если бы у меня был Oracle то я бы сделал TimeStamp & RequestTime материализованными представлениями (Google — materialized views). тогда база будет сама подсчетом атрибута number заниматся. а в Request вставлял бы так
insert into request (...) select ?, ?, ? from dual where not exists (select 0 from request where md5 = ? and ...);
Привет всем, у меня такая проблема, я заметил что при использовании 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 мог бы сохранять в текстовые файлы, возможно это было бы приемлемо.
Здравствуйте, 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?
Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.
Здравствуйте, 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 в таком случаи?
Все верно пишет.
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) как будет вести себя тригер, если он не успеет сделать выборку или посчитать что-то, как к ниму приходит уже новый инсёрт, если он их будет обрабатывать по очереди, то тогда ничего страшного, но если каждый отдельно то получится каша, на чей совести остаётся проблема синхронизации?
да и в каком случаи использовать триггеры, а в каком хранимые процедуры?
U>да и в каком случаи использовать триггеры, а в каком хранимые процедуры?
Что бы не мучится, пишите все в хранимых процедурах и, когда надо, вызывайте их в триггерах.
"СССР — четыре слова и все лживые" — Вагрич Бахчанян
DM>Что могу посоветовать (у меня тоже не сразу быстро заработало): DM>- проверить, как hibernate генерит ключи (я поставил increment); DM>- выключить лог. Несмотря на batch-операцию, лог hibernate пишет для каждого объекта;
а как его выключить, можешь предсавить свой код, или на мыло выслать весь проект, что желательно unkis@gmx.de
Здравствуйте, unkis, Вы писали:
DM>>Что могу посоветовать (у меня тоже не сразу быстро заработало): DM>>- проверить, как hibernate генерит ключи (я поставил increment); DM>>- выключить лог. Несмотря на batch-операцию, лог hibernate пишет для каждого объекта; U>а как его выключить, можешь предсавить свой код, или на мыло выслать весь проект, что желательно unkis@gmx.de
В моем случае для выключение лога понадобилось:
— в hibernate.cfg.xml свойство hibernate.show_sql установлено в false
— в конфигурации лога log4j.xml установлено
Здравствуйте, danila.master, Вы писали:
DM>Oracle Oracle'у рознь. Я на удаленном сервере тестился. DM>Сейчас проверил локально — результат значительно ухудшился (чего и следовало ожидать). На 100 000 записей: DM>jdbc = 6.953 DM>hbn = 12.234
да, это уже больше похоже на правду. еще можно параллально в нескольких потоках попробовать вставку делать. ну, и разный тюнинг вроде игры с размером TCP пакета, разный размер batch, использованием массива вместо отдельных инсертов и т.д.
плюс, нужно, естественно, сначала пару раз прогнать код без замера времени, чтобы JVM разогрелся, ну, и -server -Xbatch тоже поможет.
но, в целом overhead гибернэйта в данном случае очень большой, а толку от него в данном тесте нет никакого, в т.ч. кода больше за счет XML дескрипторов. кстати, hibernate у тебя Oracle sequences использует?
Здравствуйте, n0name2, Вы писали:
N>Здравствуйте, danila.master, Вы писали:
DM>>Oracle Oracle'у рознь. Я на удаленном сервере тестился. DM>>Сейчас проверил локально — результат значительно ухудшился (чего и следовало ожидать). На 100 000 записей: DM>>jdbc = 6.953 DM>>hbn = 12.234
N>да, это уже больше похоже на правду. еще можно параллально в нескольких потоках попробовать вставку делать. ну, и разный тюнинг вроде игры с размером TCP пакета, разный размер batch, использованием массива вместо отдельных инсертов и т.д.
N>плюс, нужно, естественно, сначала пару раз прогнать код без замера времени, чтобы JVM разогрелся, ну, и -server -Xbatch тоже поможет.
Это да. Но меня тут порядок величины интересовал. У автора ветки разница получается более чем в 100 раз.
N>но, в целом overhead гибернэйта в данном случае очень большой, а толку от него в данном тесте нет никакого, в т.ч. кода больше за счет XML дескрипторов.
Для теста конечно толку нет А в определенном классе задач такое решение может быть вполне оправдано. Для большой и сложной схемы БД разработка и поддержка второго mapping'а для jdbc потребует больших усилий. Если производительность операций загрузки данных не является наиболее приоритетной/критичной или объем данных не сильно большой, можно и через hibernate грузить.
Кроме того, подозреваю, что основные затраты в hibernate связаны с использованием reflection. Так что если данные представлены в виде бинов, то выигрыш от jdbc может быть значительно меньше (для унифицированных решений). С другой стороны, hibernate можно привязать не к бинам, а к Map. Интересно, какой для этого случая получился бы результат.
N> кстати, hibernate у тебя Oracle sequences использует?
Обычно использую sequence, но для теста включил increment.
Здравствуйте, danila.master, Вы писали:
DM>Это да. Но меня тут порядок величины интересовал. У автора ветки разница получается более чем в 100 раз.
в 100 раз, конечно, перебор...
DM>Для теста конечно толку нет А в определенном классе задач такое решение может быть вполне оправдано. Для большой и сложной схемы БД разработка и поддержка второго mapping'а для jdbc потребует больших усилий. Если производительность операций загрузки данных не является наиболее приоритетной/критичной или объем данных не сильно большой, можно и через hibernate грузить.
это все понятно. просто народ стал кидатся HBN юзать везде не задумываясь. причем, ИМХО, этот класс задач уже чем многие думают.
DM>Кроме того, подозреваю, что основные затраты в hibernate связаны с использованием reflection. Так что если данные представлены в виде бинов, то выигрыш от jdbc может быть значительно меньше (для унифицированных решений). С другой стороны, hibernate можно привязать не к бинам, а к Map. Интересно, какой для этого случая получился бы результат.
думаю, примерно также. Map add/put тоже не сахар.
DM>Обычно использую sequence, но для теста включил increment.
это некорректно. нужно sequences юзать, иначе вообще смысла нет никакого в инсертах. кстати, HBM "insert (...) values (...) returining ?" ситнаксис использует?
Здравствуйте, n0name2, Вы писали:
N>Здравствуйте, danila.master, Вы писали:
DM>>Обычно использую sequence, но для теста включил increment.
N>это некорректно. нужно sequences юзать, иначе вообще смысла нет никакого в инсертах.
А почему некорректно? Судя по описанию задачи тут явно пакетная загрузка данных. Маловероятно, что нужны ключи создаваемых объектов.
N>кстати, HBM "insert (...) values (...) returining ?" ситнаксис использует?
Судя по всему, нет. Есть sequence-identity (только для Oracle 10g), а можно самому написать.
Здравствуйте, danila.master, Вы писали:
N>>это некорректно. нужно sequences юзать, иначе вообще смысла нет никакого в инсертах. DM>А почему некорректно? Судя по описанию задачи тут явно пакетная загрузка данных. Маловероятно, что нужны ключи создаваемых объектов.
если у тебя кто-то еще данные параллельно пишет, то будет конфликт ключей.
Здравствуйте, n0name2, Вы писали:
N>Здравствуйте, danila.master, Вы писали:
N>>>это некорректно. нужно sequences юзать, иначе вообще смысла нет никакого в инсертах. DM>>А почему некорректно? Судя по описанию задачи тут явно пакетная загрузка данных. Маловероятно, что нужны ключи создаваемых объектов.
N>если у тебя кто-то еще данные параллельно пишет, то будет конфликт ключей.
Это так. Мне почему-то казалось, что в обсуждаемой задаче эта ситуация отсутствует. Но это, конечно, только предположение (судя по названиям бинов — Request, RequestTime, TimeStamp — не правильное).
Здравствуйте, danila.master, Вы писали:
DM>Это так. Мне почему-то казалось, что в обсуждаемой задаче эта ситуация отсутствует. Но это, конечно, только предположение (судя по названиям бинов — Request, RequestTime, TimeStamp — не правильное).
короче, корректный тест сложно сделать. но, для большого кол-ва легких запросов HBN тормозит, это точно.
DM>>Это так. Мне почему-то казалось, что в обсуждаемой задаче эта ситуация отсутствует. Но это, конечно, только предположение (судя по названиям бинов — Request, RequestTime, TimeStamp — не правильное).
Задача на самом деле выглядит так:
Есть как вы уже заметили следующие таблицы:
TimeStamp <------>RequestTime<--------> Request
так вот в RequestTime есть атрибут number, который отображает количество Request в определенное время(TimeStamp).
То есть перед тем как произвести вставку в БД, нужно произвести проверку: существует ли такой же Request в БД и Существует ли такой же TimeStamp в БД и если они существуют, то для них уже существует запись в промежуточной таблицы RequestTime, тогда получить эту запись, то есть объект RequestTime, и увеличить атрибут number на один, и после этого произвести апдейт объекта RequestTime.
Проверка, существует ли объект в БД или нет, это проверка почти всех атрибутов объекта в БД, на равенство всех атрибутов нового объекта.
так что вот такая вот задача.
для решение которой я применил следующий фокус.
самая большая потеря времени это сравнения двух объектов по всем атрибутом, чтобы это избежать я подписываю все атрибуты MD5 и это является моим ключом для этого объекта.
Таким образом мы получаем проверку не по всем атрибутам, а только по ключу, то во много раз быстрее.
Но ту всё равно получается что пред каждой вставкой мне надо делать в худшем случаи три выборки, а в лучшем случаи только две. Вот и задача как всё это ускорить.
Здравствуйте, n0name2, Вы писали:
U>>Вот и задача как всё это ускорить.
N>ты самое главное не написал — какая именно база у тебя. кстати, сверять ТОЛЬКО MD5 — неверно т.к. две строки могут иметь одинаковый hash и разные данные. нужно сверять и то и другое, сначала MD5 (а лучше SHA-1), конечно.
База у меня MySQL, А можно немножко поп подробней про MD5, я что-то не понял почему они ьогут быть одинаковыми?
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, unkis, Вы писали:
U>>А можно немножко поп подробней про MD5, я что-то не понял почему они ьогут быть одинаковыми? B>Тю, это же логика. B>1) Множество всех строк больше чем множество всех их MD5 hash кодов. Это надо объяснять почему?
извини за глупость, но всё же хотелось бы услышать
А как насчёт SHA алгоритма, там как дела обстоят с этим?
Здравствуйте, unkis, Вы писали:
U>Здравствуйте, Blazkowicz, Вы писали:
B>>Здравствуйте, unkis, Вы писали:
U>>>А можно немножко поп подробней про MD5, я что-то не понял почему они ьогут быть одинаковыми? B>>Тю, это же логика. B>>1) Множество всех строк больше чем множество всех их MD5 hash кодов. Это надо объяснять почему? U>извини за глупость, но всё же хотелось бы услышать
сколько различных MD5 кодов может быть? 2^128 (длина digest'а 128 bit = 16 байт)
сколько различных строк может быть? если предположить, что символ это 1 байт, количество различных строк длиною 16 байт будет тоже 2^128. Но кроме строк длиною 16 байт существуют строки длиною 15 байт, 14 байт, 0 байт а также 17 байт, 18 байт... Получается, что мощность множества всех строк строго больше мощности множества всех MD5 кодов. Следовательно взаимно однозначного отображения между ними быть не может.
U>А как насчёт SHA алгоритма, там как дела обстоят с этим?
Точно так же. Как и с любым другим digest'ом.
Здравствуйте, dshe, Вы писали:
D>Здравствуйте, unkis, Вы писали:
U>>Здравствуйте, Blazkowicz, Вы писали:
B>>>Здравствуйте, unkis, Вы писали:
U>>>>А можно немножко поп подробней про MD5, я что-то не понял почему они ьогут быть одинаковыми? B>>>Тю, это же логика. B>>>1) Множество всех строк больше чем множество всех их MD5 hash кодов. Это надо объяснять почему? U>>извини за глупость, но всё же хотелось бы услышать D>сколько различных MD5 кодов может быть? 2^128 (длина digest'а 128 bit = 16 байт) D>сколько различных строк может быть? если предположить, что символ это 1 байт, количество различных строк длиною 16 байт будет тоже 2^128. Но кроме строк длиною 16 байт существуют строки длиною 15 байт, 14 байт, 0 байт а также 17 байт, 18 байт... Получается, что мощность множества всех строк строго больше мощности множества всех MD5 кодов. Следовательно взаимно однозначного отображения между ними быть не может.
U>>А как насчёт SHA алгоритма, там как дела обстоят с этим? D>Точно так же. Как и с любым другим digest'ом.
вот блин а как же тогда решить такую проблему?
Есть какие-то идеи?
Здравствуйте, unkis, Вы писали:
U>>>А как насчёт SHA алгоритма, там как дела обстоят с этим? D>>Точно так же. Как и с любым другим digest'ом.
U>вот блин а как же тогда решить такую проблему? U>Есть какие-то идеи?
Так а в чем проблема? Как я понял, MD5 используется для ускорения выборки из СУБД. Для этого он хорошо будет работать. Достаточно дополнительно вставить проверку по всем значащим полям (в select или в java-коде после загрузки объекта).
Здравствуйте, danila.master, Вы писали:
DM>Здравствуйте, unkis, Вы писали:
U>>>>А как насчёт SHA алгоритма, там как дела обстоят с этим? D>>>Точно так же. Как и с любым другим digest'ом.
U>>вот блин а как же тогда решить такую проблему? U>>Есть какие-то идеи?
DM>Так а в чем проблема? Как я понял, MD5 используется для ускорения выборки из СУБД. Для этого он хорошо будет работать. Достаточно дополнительно вставить проверку по всем значащим полям (в select или в java-коде после загрузки объекта).
А как вы думаете, могут ли быть грабли, если сделать следующее:
В место подписи SHA1, генерировать id просто объединяя строки.
К примеру, есть атрибуты A,B,C,D, так вот id будет равен "A-B-C-D"
интересно какие грабли могут быть в таком варианте?
Здравствуйте, unkis, Вы писали:
U>А как вы думаете, могут ли быть грабли, если сделать следующее: U>В место подписи SHA1, генерировать id просто объединяя строки. U>К примеру, есть атрибуты A,B,C,D, так вот id будет равен "A-B-C-D" U>интересно какие грабли могут быть в таком варианте?
Маленькие грабельки:
A="a-x"
B="b"
и
A="a"
B="x-b"
После объединения дадут одинаковую строчку "a-x-b". Легко обходятся если есть символ, который заведомо не встречается в исходных строках, и не так легко если такого символа нет.
Так а чем вам не нравится вариант с MD5? Дополнительной проверкой в java-коде?
RT>Маленькие грабельки: RT>A="a-x" RT>B="b" RT>и RT>A="a" RT>B="x-b" RT>После объединения дадут одинаковую строчку "a-x-b". Легко обходятся если есть символ, который заведомо не встречается в исходных строках, и не так легко если такого символа нет.
RT>Так а чем вам не нравится вариант с MD5? Дополнительной проверкой в java-коде?
А не нравится мне это по следующей причине.
К примеру, я создаю новый объект, генерирую ключ, получаю md5, далее, делаю выборку по этому ключу, получаю объект из БД, сравниваю все атрибуты и вижу что ключ одинаковый, а поля не совпадают. и вот тут возникает вопрос, что сделать с моим(созданным) объектом?
Есть идеи?
Здравствуйте, unkis, Вы писали:
RT>>Так а чем вам не нравится вариант с MD5? Дополнительной проверкой в java-коде? U>А не нравится мне это по следующей причине. U>К примеру, я создаю новый объект, генерирую ключ, получаю md5, далее, делаю выборку по этому ключу, получаю объект из БД, сравниваю все атрибуты и вижу что ключ одинаковый, а поля не совпадают. и вот тут возникает вопрос, что сделать с моим(созданным) объектом? U>Есть идеи?
Кладете его в базу и не напрягаетесь лишний раз по этому поводу
В следующий раз, когда будете искать объект по md5 select (ну или EJBQuery) вернет вам два объекта и сравнив остальные поля вы выберете нужный экземпляр. Да и вобще, за время жизни вашей программы это пренеприятнейшее событие произойдет от силы несколько раз (а скорее всего вообще ни разу).
Здравствуйте, unkis, Вы писали:
RT>>Кладете его в базу и не напрягаетесь лишний раз по этому поводу
U>как же я его положу в базу, если у меня md5 является ключом? база будет против иметь два одинаковых значения .
короче так:
create table t (
sha1hash char(40),
col01 number,
col02 number,
col03 number,
primary key (col01, col02, col03)
);
create index sha1hash_idx on t(sha1hash);
....
select * from t where sha1hash = ? and col01 = ? and col02 = ? and col03 = ?
примерно так надо делать выборку. это будет быстро т.к. sha1hash_idx индекс высокоселективный.