2013-09-13 2 views
0

Текущий случай довольно сложный, но я могу от него избавиться. У меня есть объекты 300k (или больше, число только для статистики) в ConcurrentQueue <>, и эти объекты готовы к хранению в базе данных. Im использованием нескольких потоков, чтобы сделать запись в database.Every нить делает следующее, пока очередь не пуста:Хранение объектов async с NHibernate, Тесты производительности

  1. если можно
  2. из очереди
  3. взять объект
  4. открыть сеанс
  5. открыт транзакция
  6. сохраняются объекту
  7. фиксации транзакции
  8. закрыть сеанс
  9. перейти к 1.

После некоторого тестирования приведены результаты

  • 2 нити persits 300 тыс объектов для 00: 00: 49,4008256 averege время
  • 4 потока persits 300 тыс объектов для 00:00: 29.6146939 averege время
  • 10 нитей persits 300 тыс объектов для 00: 00: 24.0903779 averege время
  • 20 нитей persits 300 тыс объектов для 00: 00: 19.7451293 averege время
  • 40 нитей persits 300 тыс объектов для 00: 00: 18,2760453 averege время

И здесь идет мои вопросы:
[1] Почему, когда я удвоение числа потоков времени выполнения не два раза снизилась?
[2] И все равно можно улучшить это, не увеличивая количество объектов в транзакции.

Я использую NHibernate с MSSQL 2012.

+0

Надеюсь, это не настоящая 'goto'! – weston

+0

lol, no im using while (toBePersisted.TryDequeue (out obj)) –

+1

Простой ответ не использует NHibernate для этой задачи. Вы можете ускорить сеанс без сохранения состояния, но я бы использовал правильный инструмент для работы. Что-то вроде SQLBulkCopy http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx – Rippo

ответ

1

Что касается вашего вопроса
[1] Почему, когда я удваиваю количество потоков, время выполнения не уменьшается вдвое?
Нет необходимости, чтобы при увеличении потока вы могли закончить свою работу раньше.
И причиной этого может быть любая вещь, такая как доступная память, или другой ресурс - это меньше, чтобы запустить приложение. Именно ОС решит все это.

+0

Я могу объяснить это глубоко, если необходимо, но нижняя строка состоит в том, что удвоение потока не дает вам гарантии, что это сократит ваше время, все о доступных ресурсах – Jageen

1

Вы можете удвоить количество потоков, но вы просто перемещаете узкое место на экземпляр SQL-сервера. Вы не удвоили ресурсы, которые должны выполнить одну и ту же работу за половину времени.

Мне хотелось бы видеть код темы, если это возможно, не могу думать ни о каких советах.

+0

Код довольно прямолинейный, ничего сложного - общий экземпляр ConccurentQueue <> и ряд потоков, обслуживающих его. О ресурсах mssql - все советы о том, как это сделать? –

+0

Посмотрите на физические ресурсы на сервере, что забито? Память, процессор, сеть? Затем вам необходимо увеличить ресурс, находящийся под давлением, например. установите больше оперативной памяти. Возможно, стоит также взглянуть на профилировщик SQL, чтобы увидеть, медленны ли вставки, а если есть, возможно, есть причины для этого, необязательные индексы, которые вы могли бы сбросить, чтобы ускорить вставку. Проверьте это на медленных вставках: http://stackoverflow.com/a/2457862/360211 – weston

+1

У вас абсолютно должно быть 1 объект за транзакцию? Я думаю, вы знаете, что это поможет. Вставки Bult, предполагающие, что NHibernate будет их использовать, быстрее, чем синглы. – weston

Смежные вопросы