Никогда не доверяй собаке с оранжевыми бровями.
Здравствуйте, хочу посоветоваться.
Несколько лет успешно программировала мелкие проги, а тут понадобилась более объемная, и очень не хвататет теоретических знаний.
Java в среде NetBeans, JDBC.
Сама программа довольно простая, есть таблица в базе где-то на 100 тыс строк, и нужно проверить сочетания всех строк по некоей математической формуле, и выбрать наиболее подходящее сочетания по определенным требованиям. Со всем этим я справилась, но процесс занимает слишком много времени. Добавила многопоточность, все равно слишком долго. Как вообще обычно решают подобные вопросы, может подходящее железо поможет? В нем я вообще ничего не смыслю.
Несколько лет успешно программировала мелкие проги, а тут понадобилась более объемная, и очень не хвататет теоретических знаний.
Java в среде NetBeans, JDBC.
Сама программа довольно простая, есть таблица в базе где-то на 100 тыс строк, и нужно проверить сочетания всех строк по некоей математической формуле, и выбрать наиболее подходящее сочетания по определенным требованиям. Со всем этим я справилась, но процесс занимает слишком много времени. Добавила многопоточность, все равно слишком долго. Как вообще обычно решают подобные вопросы, может подходящее железо поможет? В нем я вообще ничего не смыслю.
В текущем виде ваша задача звучит слишком обобщенно, чтобы можно было дать заведомо хороший и точный совет. Сходу несколько предложений, которые возможно в вашем случае применимы.
Может быть есть какие-то возможности из математических соображений сузить изначальную выборку и перебирать не все сочетания?
Если формула одна и та же, новые строки добавляются редко - тогда можно в базе же кэшировать результаты, выполняя какие-то вычисления только при появлении новых строк/изменении старых, а не считать каждый раз. Если формул фиксированный набор, то аналогично.
Ну и у вас еще могут быть проседания по производительности, если делаете много мелких запросов в базу вместо нескольких больших.
Reflendey,
Сочетания всех строк при таком количестве, даже если вы имели ввиду пары, это очень много.
Да, именно пары.
Если формула одна и та же, новые строки добавляются редко - тогда можно в базе же кэшировать результаты
Не вполне одна, но возможно получится сохранить элементы. Спасибо, я погуглю как это делать.
Ну и у вас еще могут быть проседания по производительности, если делаете много мелких запросов в базу вместо нескольких больших.
Возможно, у меня каждое сочетание двух строк запускается отдельным потоком, и в нем уже идет запрос. А можно запросить все данные скопом, а потом в отдельных потоках вычленить нужные строки без использования sql query?
8115,
Индексы есть, все равно медленно. Но, кажется, тормозят именно запросы.
То есть вы создаете новый поток на каждый запрос?
Не очень понятно даже как он должен выглядеть
Т.е. для меня (я если что не настоящий сварщик, с БД дел практически не имею), вообще не очень ясно как можно разбить условно такой запрос
;
на N запросов. Ну кроме как явно указывая id. В общем это кажется весьма неэффективным способом, если я правильно понял что вы делаете.
А можно запросить все данные скопом, а потом в отдельных потоках вычленить нужные строки без использования sql query
Да что-то вроде
stackoverflow.com/questions/984073/java-jdbc-la... вот примерно как тут написано. В главном потоке кладете в очередь следующее значение, а в остальных потоках из этой очереди берете результаты и обрабатываете.
Я бы как-то так попробовал.
Спасибо, вы очень помогли, буду копать в эту сторону.
Воспользовалась последним способом, отлично работает, намного быстрее. Но только на пробных партиях с меньшим количеством потоков, а когда запускаю основную, где каждая пара строк отдельным потоком, то в лучшем случае падает соединение с дерби, а в худшем - виснет весь комп. Не знаете что можно с этим сделать?
Так нет никакого смысла делать число потоков больше чем число ядер на компьютере (когда смысл создания потоков исключительно в производительности за счет параллельного исполнения, как в вашем случае). На создания потока тоже ресурсы уходят, поэтому и подвисает в итоге.
Сделайте например сразу 4 потока, и в каждом запустите функцию, которая достает элементы из очереди и обрабатывает их пока очередь не опустеет.
Да, сама уже это нагуглила и расстроилась-_- Придется переписывать и подбирать другие варианты.
Простите, что гружу вас)
Наладила 8 потоков по числу ядер. Теперь самым тормозящим элементом остались многочисленные запросы из таблицы. Решила попытаться кэшировать, каждый запрос используется по несколько сотен раз. Можно ли кэшировать резалтсет целиком?
Для кэширования использовала класс:
Немного не понял, откуда взялись многочисленные, мне казалось вы в итоге сделали с 1 запросом. Или остальные нужные уже потом для самих математических функций?
Или многочисленные в том смысле, что при вводе пользователем каждой новой функции надо опять заного считывать?
Можно ли кэшировать резалтсет целиком?
Теоретически-то конечно можно, но на деле я так прикинул размерность, если у вас 100 тысяч строк и вы рассматриваете все пары, а одна строка 10 байт скажем (а скорее всего все-таки больше), то вроде как порядка 45гигабайт занимает это.
Столько оперативной памяти у вас скорее всего нет, так что вариант отпадает. Можно конечно сериализовать попробовать это на диск, но честно говоря, не представляю даст ли это какое-то ощутимое ускорение по сравнению с генерированием из БД на лету.
Нет, функция одна. Но для каждой новой пары нужно брать данные из другой таблицы, то есть для каждой пары есть два запроса. Грустно выходит.
Теоретически-то конечно можно, но на деле я так прикинул размерность, если у вас 100 тысяч строк и вы рассматриваете все пары, а одна строка 10 байт скажем (а скорее всего все-таки больше), то вроде как порядка 45гигабайт занимает это.
У меня не совсем 100 тысяч срок. Там скорее 1200 строк, но на каждую пару этих срок нужно брать пару запросов из другой таблицы, она как раз на 100 тыс.
А как вообще обычно решаются подобные проблемы? Вроде же переборы из больших баз много где делаются. Я в принципе могу получить для обработки время на кластере, но я понятия не имею как под него писать и можно ли сперва проверить программу в домашних условиях.
Это возможно опять же сделать одним SQL запросом. Собственно SQL для того и нужен, чтобы делать такие запросы, он конечно будет большой и страшный, но это нормально.
Заодно субд сама вам все и кеширует в процессе выполнения, чтобы несколько раз одно и тоже не считывать. В любом случае быстрее будет делать все по максимуму на стороне субд, они для того и придуманы)
У меня не совсем 100 тысяч срок. Там скорее 1200 строк, но на каждую пару этих срок нужно брать пару запросов из другой таблицы, она как раз на 100 тыс.
Тогда точно можно без кластера обойтись, да и кэшировать все целиком возможно на современном компьютере, однако просто все-таки впихнуть все в один запрос, мне кажется лучше.
Тогда точно можно без кластера обойтись, да и кэшировать все целиком возможно на современном компьютере, однако просто все-таки впихнуть все в один запрос, мне кажется лучше.
То есть, кэшировать всю таблицу? А как тогда указать программе, что берешь запрос именно из кэша СУБД, а не просто из таблицы?
А как тогда указать программе, что берешь запрос именно из кэша СУБД, а не просто из таблицы?
Как я уже говорил, я не настоящий сварщик. Если вы делаете все одним запросом, то заботится извне вообще ни о чем не надо, субд сама все отпимизирует.
Если же вы хотите все-таки делать много запросов, то это "как тогда указать программе, что берешь запрос именно из кэша СУБД" зависит от субд. У вас вероятно не оракловая субд, да и ссылка не кажется свежей, но для примера docs.oracle.com/cd/B10501_01/java.920/a96654/st....
Вы все равно явно опытнее меня) Спасибо за ссылку, буду учиться. Оракловая, кажется, нетбинс же.