roadman,
В SQL Server есть общепринятый жаргон, в котором bulk insert означает не что иное как bulk insert statement. Когда говорят о каком-либо способе оптимизированной массовой загрузки данных без уточнения о каком именно, то обычно говорят bulk load - что означает, что данные загружаются либо через bulk copy program (bcp), либо через bcp_api, либо через IRowsetFastLoad либо через bulk insert statement.
...поэтому bcp_done команда имеет прямое отношение к commit. Принудительно я его для bulk insert не делаю, потому как bcp библиотека этого функционала не предоставляет.
bcp_done и есть не что иное как промежуточный commit.
затем пробегаю по всем измененным строчкам в памяти и делаю update update команда выполняется через обычный ODBC statement "update table set .... where ....", после каждой команды выполняется commit
затем пробегаю по строчкам, помеченным как удаленные и выполняю обычный ODBC statement "delete from table .... where ...". после каждой команды выполняется commit
Ваша проблема именно здесь и зарыта. Такой сценарий создаёт дикую нагрузку на дисковое устройство, на котором расположен журнал, при условии, что кеширование на запись отключено. Кроме того, не стоит делать массовые изменения строк изменяя их одну за другой отдельными командами - воспользуйтесь @@rowсount для ограничения количества изменяемых отдельной комадной строк, если другого удобного способа нет (намример, изменять диапазон ключей).
По поводу частых commit - то же наверное стоит попробовать, если это напрямую связано с кешированием диска. Как по вашему, господа, какое количество строк(байт?) было бы приемлемым в одном блоке транзакций 10, 100, ..., 1000 000?
Это зависит о размера строки, начните с сотни строк, сделайте измерения, а затем увеличьте это количество, скажем, до тысячи. Как только итоговая производительнось перестанет расти или наоборот пойдёт вниз - Вы выскочили за оптимальный размер пакета.