"Усеченный не регистрируется, что-либо" корректно. Я пошел бы далее:
Усеченный не выполняется в контексте транзакции.
преимущество скорости усеченных удаляет, должно быть очевидным. То преимущество располагается от тривиального до огромного, в зависимости от Вашей ситуации.
Однако я видел усеченный неумышленно повреждать ссылочную целостность и нарушать другие ограничения. Власть, которую Вы получаете путем изменения данных вне транзакции, должна быть сбалансирована относительно ответственности, которую Вы наследовали при обходе натянутого каната без сети.
Да, это будет потоковая передача ... но я не думаю, что вы действительно должен попытаться это сделать.
Если бы вы могли читать миллион записей в секунду (что кажется мне маловероятным), вам все равно понадобилось бы 12 дней, чтобы прочитать триллион записей ... это большая работа, чтобы рискнуть потерять половину
Теперь я понимаю, что вы, вероятно, действительно не хотите читать триллион записей буквально, но я хочу сказать, что если вы все равно можете разделить свой «большой объем» работы на логические партии , наверное, хорошая идея.
Есть несколько деталей.
SqlDataReader обычно читает всю строку в памяти и кэширует ее. Сюда входят любые поля BLOB, поэтому вы можете в конечном итоге кэшировать несколько полей размером 2 ГБ в памяти (XML, VARBINARY (MAX), VARCHAR (MAX), NVARCHAR (MAX)). Если такие поля вызывают беспокойство, вы должны передать от CommandBehavior.SequentialAccess до ExecuteReader и использовать возможности потоковой передачи конкретных типов SqlClient, таких как SqlBytes.Stream .
Соединение занято до завершения SqlDataReader. Это создает транзакционные проблемы, потому что вы не сможете выполнить какую-либо обработку в базе данных в той же транзакции, потому что соединение занято. Попытка открыть другое соединение и зарегистрироваться в той же транзакции не удастся, поскольку распределенные транзакции с обратной связью запрещены. Необходимо использовать MARS . Для этого нужно установить для соединения MultipleActiveResultSets = True
. Это позволяет вам выполнять команду на том же соединении, пока устройство чтения данных все еще активно (типичный цикл fetch-process-fetch). Внимательно прочтите ссылку на Christian Kleinerman's, убедитесь, что вы понимаете проблемы и ограничения, связанные с MARS и транзакциями, они довольно тонкие и нелогичные.
Длительная обработка на клиенте блокирует сервер. Ваш запрос по-прежнему будет выполняться все это время, и серверу придется приостановить его, когда канал связи заполнится. Запрос потребляет воркера (или больше, если у него есть параллельные планы), а рабочие очень дефицитный товар на сервере (они примерно приравниваются к потокам). У вас не будет лишних денег, чтобы позволить многим клиентам обрабатывать огромные наборы результатов в свое свободное время.
Размер транзакции. Обработка триллиона записей за одну транзакцию никогда не сработает. Журнал должен будет увеличиваться, чтобы вместить всю транзакцию, без усечения и повторного использования VLF, что приведет к огромному увеличению журнала.
Время восстановления. Если обработка 999-миллиардной записи завершится неудачно, ей придется откатить всю проделанную работу, поэтому на откат уйдет еще «12» дней.
Да, это может занять некоторое время (если ваш SQL не делает ничего глупого, пытаясь сделать снимок или что-то еще), но если ваш сервер может передавать его в потоковом режиме, SqlDataReader не должен нет проблем с использованием памяти.