Как улучшить скорость моего программного проекта? - PullRequest
5 голосов
/ 18 мая 2010

Я делаю школьный программный проект с моими одноклассниками на Java. Мы храним информацию на удаленной базе данных.

Когда мы запускаем приложение, мы извлекаем все информацию из базы данных и преобразуем ее в объекты для использования в нашем приложении (используя java sql statemens). В приложении мы редактируем некоторые из этих объектов, а затем при выходе из приложения мы сохраняем или обновляем информацию в базе данных, используя Hibernate.

Как вы видите, мы не используем Hibernate для извлечения информации, мы используем его только для сохранения и обновления.

У нас 2, но очень похожие проблемы. Загрузка объекта (при запуске приложения) и сохранение объектов (с помощью Hibernate) в БД (при закрытии приложения) занимает слишком много времени. И наш проект - это не огромное корпоративное приложение, это довольно маленькое приложение, мы просто управляем некоторыми студентами, учителями, домашними заданиями и тестами. Таким образом, наша база данных также очень, очень мала. Как мы можем увеличить производительность?

позднее редактирование: если мы используем локальную базу данных, она работает очень быстро, просто она работает медленно на удаленных базах данных

Ответы [ 11 ]

7 голосов
/ 18 мая 2010

Вы говорите, что загружаете всю базу данных в память, а затем манипулируете ею? Если это так, почему бы вам просто не использовать базу данных в качестве устройства хранения и выполнять поиск и манипулирование по мере необходимости (используя Hibernate, если хотите, или что-то еще, если вы этого не делаете)? Главное, чтобы убедиться, что вы используете пул соединений, так как это сократит время соединения.

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

4 голосов
/ 18 мая 2010

Эти 2 предложения - красные флаги для меня:

Когда мы запускаем приложение, мы тянем вся информация из базы данных и превратить его в объекты для использования в нашем приложении (используя Java SQL statemens). В приложении мы редактируем некоторые из этих объектов, а затем, когда мы выйти из приложения мы сохраняем или обновляем информация в базе данных с использованием Hibernate.

Существует ли причина, по которой вы загружаете всю информацию из базы данных в память при запуске, или почему вы ждете до выключения, чтобы сохранить изменения обратно в базу данных?

Если нет, я бы предложил изменить дизайн. Если у вас уже есть отображения Hibernate для таблиц в БД, я бы использовал Hibernate для обеих ваших операций CRUD (создание, чтение, обновление, удаление). И я бы загружал только те данные, которые нужны каждой странице вашего приложения, так как это необходимо.

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

На что-то еще посмотреть. Как вы используете Hibernate для сохранения сущностей в БД? Вы делаете getHibernateTemplate (). Get для каждого, а затем делаете entity.save или entity.update для каждого? Если это так, это означает, что вы также заставляете Hibernate запускать запрос на выборку для каждого объекта базы данных перед сохранением или обновлением. Таким образом, по сути, вы будете загружать каждый объект базы данных дважды (один раз в начале программы, один раз перед сохранением). Чтобы увидеть, происходит ли это, вы можете включить свойство show_sql или использовать P6Spy , чтобы точно узнать, какие запросы выполняет Hibernate.

2 голосов
/ 18 мая 2010

Разница в загрузке всего с удаленного сервера БД по сравнению с загрузкой всего с локального сервера БД заключается в задержке в сети / размере канала. Сеть гораздо меньше, чем все остальное. Два вопроса: во-первых, сколько данных мы на самом деле говорим? Во-вторых, какова скорость вашей сети? 10/100/1000? Размер между 10 и 20% размера вашего канала будет чрезмерным из-за всего, от сетевых протоколов до самих запросов.

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

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

2 голосов
/ 18 мая 2010

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

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

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

0 голосов
/ 19 мая 2010

Спасибо за ваши ответы. Их было более чем полезно. Мы полностью решили эту проблему так:

Изменен код загрузки. Теперь он использует Hibernate с Lazy Fetching. Реорганизован код SAVE. Теперь он сохраняет только данные, которые были изменены, и сразу после того, как они были изменены. Таким образом, у нас нет ОГРОМНОГО сохранения конца.

Я поражен тем, как хорошо все прошло. Количество нового кода, которое мы должны были написать, было очень очень маленьким.

0 голосов
/ 19 мая 2010

Рассматривать основы никогда не повредит:

Улучшение скорости означает сокращение времени (очевидно), и для этого вы найдете действия, которые занимают значительное время, но можно исключить или заменить чем-то, чтоиспользует меньше времени .Под активность я подразумеваю почти всегда вызов функции, вызов метода или вызов свойства, выполняемый для определенной строки кода для определенной цели.If может вызывать ввод / вывод или может вызывать вычисления, или оба.Если его назначение не является существенным, то его можно оптимизировать.

Многие люди используют профилировщики, чтобы попытаться найти эти бесполезные строки кода, но большинство профилировщиков пропускают цель, потому что смотрят на функции, а не на строки,они засыпают во время ввода-вывода, и они беспокоятся о «собственном времени».

Многие другие люди пытаются угадать, в чем может быть проблема, или они просят других угадать, например, спрашивая SO.Такие предположения, в сущности предположений, иногда бывают правильными - чаще всего нет, но люди по-прежнему вкладывают в них время и ресурсы.

Существует очень простой способ узнать наверняка, не догадываясь, что могло бы принести пользубыть оптимизированным, и вот один из способов сделать это в Java .

0 голосов
/ 19 мая 2010

Почему у вас нет двух отдельных тем?

Тема 1 будет загружать ваши объекты один за другим. Поток 2 будет обрабатывать объекты по мере их загрузки.

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

0 голосов
/ 18 мая 2010

Некоторые другие вещи, которые вы можете посмотреть:

  • Вы можете выделить больше памяти для JVM
  • Используйте инструмент jconsole , чтобы определить узкие места.
0 голосов
/ 18 мая 2010

Поскольку ваше приложение работает медленно на удаленном сервере баз данных, я бы предположил, что потеря производительности вызвана:

Для режима гибернации вы можете использовать его пакетные функции и настроить hibernate.batch_size.

Во всех случаях, особенно когда вы не можете выполнить рефакторинг больших частей кодовой базы, используйте profiler (метод time или sql запросов), чтобы найти узкое место. Бьюсь об заклад, вы найдете тысячи запросов, каждый из которых принимает 10 мс RTT), которые могут быть объединены в один.

0 голосов
/ 18 мая 2010
  1. Попробуйте свести к минимуму количество запросов SQL, поскольку каждый запрос имеет свои накладные расходы.
  2. Вы можете включить сжатие базы данных, что должно ускорить процесс при большом количестве данных.
  3. Может быть, вы подключаетесь к базе данных много раз?
  4. Проверьте время проверки связи с удаленным сервером базы данных - возможно, это проблема.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...