Самый быстрый способ записать множество небольших значений BLOB в базу данных SQL Server на С#

Что я хочу сделать:

Напишите много небольших (в среднем 500-1000 байт) объектов, похожих на блобы, которые я получаю из очереди в базу данных SQL Server, в таблицу с первичным ключом bigint и данными в виде столбца varbinary.

В настоящее время я делаю это так:

  1. получить некоторый объект из параллельной очереди
  2. создать новый поток памяти и новый бинарный писатель
  3. сериализовать объект в поток памяти с помощью команды Write... из модуля записи
  4. вызовите stream.ToArray() и установите результат в качестве значения параметра команды SQL
  5. выполнить команду

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

Но похоже, что объекты SqlCommand внутренне копируют буфер, если вы передаете массив байтов.

Также проблема повторного использования одного и того же массива байтов снова и снова заключается в том, что я не могу сказать SqlCommand, сколько байтов он должен записать в таблицу (каждый объект будет иметь немного другую длину)

Любая идея, как это сделать без написания моей собственной реализации SQL?


person user1803928    schedule 08.02.2017    source источник
comment
Честно говоря, если задействовано сетевое соединение, ничтожное количество времени, затрачиваемое на потенциальный сборщик мусора, является наименьшей из ваших проблем. Преждевременная оптимизация   -  person MickyD    schedule 08.02.2017
comment
в моем случае это не так, потому что, поскольку мне все равно, сколько времени потребуется, чтобы данные попали в базу данных, вся запись является асинхронной, потому что это система высокой доступности, которая должна иметь минимальные задержки. Меня не волнует, займет ли запись 100 мс или 200 мс, но меня волнует возможное прерывание GC (ну, это должно быть очень быстро, но лучше быть немного медленнее и не влиять на GC)   -  person user1803928    schedule 08.02.2017
comment
Предполагая, что вы используете .NET 4+, вы обнаружите, что GC довольно эффективен и быстр по сравнению с шаром и цепью до .NET 4. .NET 4, работающий на рабочих станциях Windows, выполняет GC в фоновом потоке, а серверы выполняют фоновый GC на .NET 4.5, поэтому вероятность того, что текущий поток зависнет во время сбора, мала. Если ваша система действительно высокоэффективна, она должна иметь достаточную спецификацию. Если у вас нет фактических результатов сеанса инструментирования, показывающих значительные задержки в вашем коде, вызванные чрезмерными сборами, я думаю, что беспокойство, возможно, немного необоснованно.   -  person MickyD    schedule 08.02.2017
comment
Если вы так беспокоитесь о GC, имейте в виду, что использования простого foreach достаточно, чтобы создать временный объект итератора, который в конечном итоге потребует его сбора. Эффект усиливается в зависимости от частоты использования. Используйте его достаточно, и это тоже повод для заикания. Спросите любого разработчика игр XNA или Unity3D, который, к сожалению, застрял с технологией до .NET 4. Вот почему они используют for вместо foreach. Но меня беспокоит .NET 4.5 на Windows Server? Нет   -  person MickyD    schedule 08.02.2017