Написание кода для обработки 25 000 записей C #, T-SQL, быстродействие является ключевым - PullRequest
0 голосов
/ 11 апреля 2011

Какой был бы наиболее эффективный способ перебрать 25 000 записей и, основываясь на некоторой заранее написанной логике vb, которая никогда не изменится (уверен на 99%), обновить столбец Result в таблице до значения 1, 2 или 3?

Производительность и надежность здесь важнее всего.Это, скорее всего, будет вызвано через клиент-серверное приложение в сети, но было бы неплохо иметь возможность вызывать его из веб-приложения.Я думаю о 3 разных способах сделать это с T-SQL, C #.

a.Запись объекта, который выполняет хранимую процедуру, получает 25 000 записей, использование коллекции foreach для просмотра каждой записи и на основе некоторой логики c # вызов объекта в каждой записи, которая выполняет хранимую процедуру, для обновления этой строки.Это вызвало бы объект 25 000 раз (и процедура, которую я предполагаю, просто использовала бы план выполнения)

или

b.Напишите хранимую процедуру, которая получает 25 000 записей, используйте запрещенный курсор для просмотра каждой записи и, основываясь на некоторой логике T-SQL, обновите эту строку в этой хранимой процедуре.

или

ОБНОВЛЕНО: МОЕ РЕШЕНИЕ ЭТО ТОЛЬКО Я собираюсь использовать сохраняемые вычисляемые столбцы и разбивать цикл на более мелкие операторы обновления для обновления столбца (все обернуто в транзакцию),Смотрите статью ниже.Я думаю, что это будет действительно быстро, по сравнению с циклом ..

http://technet.microsoft.com/en-us/library/cc917696.aspx

Ответы [ 8 ]

7 голосов
/ 11 апреля 2011

У вас, очевидно, есть какое-то условие, определяющее, должно ли значение быть 1,2 или 3. Вы можете просто выполнить 3 запроса на обновление.Каждый запрос будет обновлять записи на основе условия, которое определяет, должно ли значение быть 1, 2 или 3. Не передавайте все данные на свой компьютер, если вы можете помочь ему.

2 голосов
/ 11 апреля 2011

Моим первым выбором было бы сделать все это в SQL, если бы я мог, то есть обновить xxx set col = 1 где (ваша логика здесь), обновить xxx set col = 2 где (логика) и т. Д.

Если вам нужно для выполнения логики в клиенте vb, либо в веб-приложении, либо на клиентском сервере, я бы выбрал использование устройства чтения данных для передачи через записи (опуская только столбцы требуется не вся строка) и либо выполнить обновление TSQL, либо хранимую процедуру, чтобы вызвать те записи, которые необходимо обновить, по одной за раз).

считыватель данных даст вам наилучшую производительность; SP должен работать по крайней мере так же хорошо, если не лучше, чем обновление TSQL (но, вероятно, не намного).

РЕДАКТИРОВАТЬ: Избегайте серверных курсоров практически (любой) ценой ... они настоящие свиньи.

1 голос
/ 11 апреля 2011

Решение без ввода c # на самом деле является лучшим вариантом, если производительность является ключевым фактором. Запустите ваши запросы за пределами C #. Если это действительно необходимо, используйте DataReaders.

0 голосов
/ 19 декабря 2012

У меня похожая ситуация. На самом деле, у меня есть> 10.000.000 записей. Бизнес-логика была довольно сложной, и старый код был написан исключительно на SQL. Менеджеры сказали мне, что со старым кодом это занимает более 15 часов на 1 000 000 записей. С моим решением я потратил всего 5 минут, буквально! Я сделал это в цикле, который имеет 3 шага в итерации, и каждая итерация занимала одну партию записей:

  1. Массовая загрузка счетов. Я не помню размер партии, я думаю, это было несколько тысяч.
  2. Выполнение бизнес-логики для загруженных записей
  3. Массовая вставка. Поскольку это было много, это не могло быть обновлено. Таким образом, он был перенесен во временную таблицу с почти такой же структурой, что и исходная таблица, а затем обновлен по ключу в исходной таблице. Временная таблица очищалась / удалялась при каждой массовой вставке. Это намного быстрее, чем стандартное обновление.
0 голосов
/ 12 апреля 2011

Вы можете либо:

  1. Перейти к 3 отдельным ОБНОВЛЕНИЯМ, предложенным @ Andrew

  2. Извлечь записи во временную таблицу и выполнить циклчерез них, возможно, по 1000 записей за раз в цикле WHILE для оператора UPDATE (так, 25 циклов / UPDATE)

  3. Или, если вы используете SQL Server 2008 (илиновее) и алгоритм определения изменения сложен, вы можете вытащить 25 000 строк в коллекцию на стороне .Net и направить изменения обратно в Proc с табличным параметром и выполнить одно обновление.Вы можете найти пример этого по адресу:
    http://www.sqlservercentral.com/articles/SQL+Server+2008/66554/

В каждом случае вы хотите избежать 25 000 вызовов UPDATE.

0 голосов
/ 11 апреля 2011

В зависимости от того, как работают обновления, у вас есть несколько вариантов.

  1. Есть вычисляемый столбец, в котором результаты сохраняются.Таким образом, когда запись изменится, она будет обновлена ​​в одном месте.

  2. Вместо выполнения 25 000 запросов на обновление, просто используйте sqlbulk load.

  3. (и это мое предпочтение).Пусть ваше приложение отправит параметры SQL-серверу на предмет обновления.В этом случае я бы склонялся к использованию статического курсора, поскольку он был бы немного быстрее, если одна запись не обязательно влияет на следующую.

0 голосов
/ 11 апреля 2011

Как насчет опции (C) Хранимая процедура, которая обновляет таблицу с использованием логики на основе набора, а не курсора:

...
update x set col = f(x)
from   x
...
0 голосов
/ 11 апреля 2011

Я бы не стал использовать вариант B. По моему опыту, использование курсоров чрезвычайно медленное.

C.Используйте DataReader и обновите записи с помощью ExecuteNonQuery

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...