У меня есть база данных в SQL Server 2012 и хочу обновить таблицу.
Моя таблица имеет три столбца, первый столбец имеет тип nchar(24)
. Он заполнен миллиардом строк. Остальные две колонн из того же типа, но они null
(пустые) в этот момент.
Мне нужно прочитать данные из первого столбца, с этой информацией я делаю некоторые вычисления. Результатом моих вычислений являются две строки, две строки - это данные, которые я хочу вставить в два пустых столбца.
Мой вопрос - это самый быстрый способ прочитать информацию из первого столбца таблицы и обновить второй и третий столбцы.
Прочитайте и обновите шаг за шагом? Прочитайте несколько строк, выполните расчет, обновите строки, читая следующие несколько строк?
Что касается миллиарда строк, производительность здесь важна.
Дайте мне знать, если вам нужна дополнительная информация!
EDIT 1: Мой расчет не может быть выражен в SQL. Поскольку SQL-сервер находится на локальной машине, проблема в том, что нам не нужно беспокоиться. Один расчет занимает около 0,02154 секунды, у меня есть общее количество строк 2.809.475.760, это около 280 ГБ данных.
Linq довольно эффективен из моего опыта. Я бы не стал слишком беспокоиться об оптимизации вашего кода. На самом деле это то, что вам следует избегать, преждевременно оптимизируя ваш код, просто попробуйте сначала работать, а затем рефакторинг по мере необходимости. В качестве побочной заметки я однажды проверил хранимую процедуру на запрос Linq, и Linq выиграл (к моему удивлению)
Обычно DML лучше всего выполнять в больших партиях. В зависимости от вашей структуры индексирования небольшой размер партии (возможно, 1000?!) может уже обеспечить наилучшие результаты или вам могут потребоваться большие размеры пакета (вплоть до того, что вы будете писать все строки таблицы в одном заявлении).
Массовые обновления могут выполняться с помощью массовой вставки информации об обновлениях, которые вы хотите внести, а затем обновления всех строк в пакете в одном выражении. Существуют альтернативные стратегии.
Поскольку вы не можете держать все строки обновляемыми в памяти одновременно, вам, вероятно, нужно будет заглянуть в MARS, чтобы иметь возможность выполнять потоковое чтение во время записи одновременно в одно и то же время. Или вы можете сделать это с двумя соединениями. Будьте осторожны, чтобы не блокировать соединения. SQL Server не может обнаружить это в принципе. Только тайм-аут разрешит такой (распределенный) тупик. Создание читателя под изоляцией моментальных снимков - хорошая стратегия. Изоляция снимка заставляет читателя блокировать или блокировать.
Нет простого способа и единого решения для всех здесь.
Если есть миллиарды строк, важна ли производительность? Мне не кажется, что это нужно сделать за секунду.
Какова ожидаемая пропускная способность базы данных и сети. Если у вас за номером телефонной линии POTS, то случай на корпусе 10Gb значительно отличается.
Вычисления? Насколько они дороги? Просто c = a + b или тяжелая обработка других текстовых файлов.
Всего несколько вопросов, поднятых в ответ. Как таковой, гораздо более важно, что мы не знаем, как правильно ответить.
Попробуйте пару вещей и измерите их.
Как правило: запись в базу данных может быть улучшена путем пакетной обработки вместо отдельных обновлений.
Использование async-шаблона может освобождать часть времени для вычислений вместо ожидания.
РЕДАКТИРОВАТЬ в ответ на комментарий Если вычисления составляют 20 мсек, самой большой проблемой является IO. Многопоточность не принесет вам многого. Прочитайте записи в последовательности, используя изоляцию моментальных снимков, чтобы она не мешала блокировкам записи и обновлялась партиями. Я предполагаю, что читатель остается без проблем перед читателем, чтение в партиях добавляет сложности, не принося многого.
Найдите сладкое пятно для правильной партии, экспериментируя.
UPDATE MyTable SET Col2 = substring(Col1,1,12), Col3 = substring(Col1,12,12)
(я использовал в качестве примераsubstring
).