Наше приложение должно добавлять большие объемы текста в базу данных SQL Server 2005 (до 1 ГБ для одной записи). По соображениям производительности это делается в чанках, путем вызова хранимой процедуры для каждого чанка (скажем, usp_AddChunk). usp_AddChunk не имеет явных транзакций.
Что я вижу, так это уменьшение размера чанка со 100 МБ до 10 МБ, что приводит к значительному увеличению журналов транзакций. Мне сказали, что это потому, что каждый раз, когда вызывается usp_AddChunk, «неявная» (мой термин) транзакция будет регистрировать весь существующий текст. Итак, для записи 150 МБ:
Размер блока 100 МБ: 100 (зарегистрировано 0 байт) + 50 (зарегистрировано 100 МБ) = зарегистрировано 100 МБ
будет меньше
10 МБ Размер блока: 10 (зарегистрировано 0 байт) + 10 (зарегистрировано 10 МБ) + 10 (зарегистрировано 20 МБ) ... + 10 (зарегистрировано 140 МБ) = зарегистрировано 1050 МБ
Я подумал, что, открыв транзакцию в моем коде C # (до того, как я добавлю первый блок и сделаю коммит после последнего блока), эта «неявная» транзакция не произойдет, и я смог бы избежать огромных файлов журнала. Но мои тесты показывают, что журнал транзакций увеличивается в 5 раз при использовании транзакции ADO.NET.
Я не буду публиковать код, но вот несколько деталей:
- Я вызываю SqlConnection.BeginTransaction ()
- Я использую разные SqlCommand для каждого чанка
- Я присваиваю SqlTransaction из (1) каждой SqlCommand
- Обычно я закрываю соединение после каждого выполнения SqlCommand, но я также пытался не закрывать соединение с теми же результатами
Какой недостаток в этой схеме? Дайте мне знать, если вам нужно больше информации. Спасибо!
Примечание: использование модели восстановления с простой или массовой регистрацией не вариант