Перечисление более 10 миллионов записей из Oracle с C # - PullRequest
8 голосов
/ 30 ноября 2011

У меня есть база данных, которая содержит более 100 миллионов записей.Я выполняю запрос, который содержит более 10 миллионов записей.Этот процесс занимает слишком много времени, поэтому мне нужно сократить это время.Я хочу сохранить полученный список записей в виде файла CSV.Как я могу сделать это максимально быстро и оптимально?Ждем ваших предложений.Спасибо.

Ответы [ 4 ]

11 голосов
/ 30 ноября 2011

Я предполагаю, что ваш запрос уже ограничен нужными вам строками / столбцами и хорошо использует индексацию.

В этом масштабе единственное критическое - это то, что вы не пытаетесь загрузить все это в память сразу; так что забудьте о таких вещах, как DataTable, и о большинстве полнофункциональных ORM (которые обычно пытаются связать строки с менеджером идентификации и / или менеджером изменений). Вы должны будете использовать либо необработанный IDataReader (из DbCommand.ExecuteReader), либо любой API-интерфейс, который создает небуферизованный итератор на top этого (их несколько; я склонен к более щадящему) , В целях написания CSV, читатель необработанных данных, вероятно, подойдет.

Кроме того: вы не можете заставить его работать намного быстрее, поскольку у вас ограниченная пропускная способность. Единственный способ ускорить его - это создать файл CSV на сервере базы данных , чтобы не было необходимости в работе сети.

5 голосов
/ 30 ноября 2011

Скорее всего, вы должны сделать это в C #.Это область массовой загрузки / экспорта данных (обычно используется в сценариях хранилищ данных).

Многие (бесплатные) инструменты (я полагаю, даже Toad by Quest Software) сделают это более надежно и более эффективно, чем вы можетенапишите это на любой платформе.

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

Я предлагаю использовать правильный инструмент для работы.И что бы вы ни делали,

  • не сверните свои собственные преобразования типов данных
  • используйте CSV с цитируемыми литералами и подумайте о том, чтобы избежать двойных кавычек внутри этих
  • , подумайте о региональных опциях(IOW: всегда используйте InvariantCulture для экспорта / импорта!)
2 голосов
/ 30 ноября 2011

"Этот процесс занимает слишком много времени, поэтому мне нужно его сократить."

Этот процесс состоит из трех подпроцессов:

  1. Получение> 10 м записей
  2. Запись записей в файл
  3. Передача записей по сети (я предполагаю, что вы работаете с локальным клиентом для удаленной базы данных)

Любойили все эти проблемы могут быть узким местом.Таким образом, если вы хотите сократить общее истекшее время, вам нужно выяснить, где оно потрачено.Вам, вероятно, понадобится использовать свой код C # для получения метрик.

Если выяснится, что запрос является проблемой, вам нужно будет его настроить.Индексы здесь не помогут, так как вы извлекаете большую часть таблицы (> 10%), поэтому поможет увеличение производительности полного сканирования таблицы.Например, увеличение памяти, чтобы избежать сортировки дисков.Параллельный запрос может быть полезен (если у вас Enterprise Edition и у вас достаточно процессоров).Также убедитесь, что проблема не связана с аппаратным обеспечением (конфликт шпинделей, хитрые межсоединения и т. Д.).

Может ли запись в файл быть проблемой?Возможно, по какой-то причине ваш диск работает медленно (например, фрагментация) или, возможно, вы конкурируете с другими процессами, выполняющими запись в тот же каталог.

Перенос больших объемов данных по сети, очевидно, является потенциальным узким местом.Вы уверены, что отправляете данные только клиенту?

Альтернативная архитектура: используйте PL / SQL для записи записей в файл на сервере данных, используя массовый сбор для извлечения управляемых пакетов записей, изатем передайте файл туда, где он вам нужен, в конце, через FTP, возможно, сначала сжав его.

1 голос
/ 30 ноября 2011

Реальный вопрос заключается в том, почему вам нужно читать так много строк из базы данных (и такую ​​большую долю базового набора данных). Существует множество подходов, которые должны сделать этот сценарий недопустимым, очевидными из которых являются синхронная обработка, организация очереди сообщений и предварительная консолидация.

Оставим это в стороне ... если вы консолидируете данные или просеиваете их, то реализация большей части логики в PL / SQL избавляет от необходимости перетаскивать данные по сети (даже если это только на localhost есть еще большие накладные расходы). Опять же, если вы просто хотите записать его в плоский файл , реализация этого в C # не принесет вам пользы.

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