Как перебрать все строки в таблице Oracle?

У меня есть таблица с ~ 30 000 000 строк, которые мне нужно перебирать, обрабатывать данные для каждой строки отдельно, а затем сохранять данные из строки в файл на локальном диске.

Каков наиболее эффективный способ перебора всех строк в таблице с использованием SQL для Oracle? Я гуглил, но не вижу простого способа сделать это. Пожалуйста помоги. Имейте в виду, я не знаю точного количества строк, только приблизительное.

РЕДАКТИРОВАТЬ ДЛЯ РАЗЪЯСНЕНИЯ:

Мы используем Oracle 10g, я думаю. Данные строки содержат данные больших двоичных объектов (сжатые текстовые файлы и файлы xml), которые будут считаны в память и загружены в пользовательский объект, где они затем будут обновлены/преобразованы с использованием классов доступа .Net DOM, заархивированы и сохранены на локальном диске. .

У меня нет большого опыта работы с базами данных - я планировал использовать прямые операторы SQL с ADO.Net + OracleCommands. На самом деле никаких ограничений по производительности. Это для внутреннего использования. Я просто хочу сделать это как можно лучше.


person JimDaniel    schedule 17.10.2009    source источник
comment
какие манипуляции нужно сделать с данными? вероятно, вы могли бы сделать это в каком-то запросе, но вы должны предоставить больше информации.   -  person twolfe18    schedule 17.10.2009
comment
Вам нужно предоставить больше информации. Вы собираетесь использовать PL/SQL, Pro*C или OCI? Или ваши манипуляции достаточно просты, вы можете сделать это в запросе, а затем экспортировать результаты в файл? Больше информации даст лучшие ответы.   -  person EvilTeach    schedule 17.10.2009
comment
Кроме того, есть ли ограничения по производительности? Какую версию оракула используете? В каком формате должен быть выходной файл? Что будет сделано с файлом потом?   -  person EvilTeach    schedule 17.10.2009
comment
Записывается ли манипуляция в базу данных вообще? В самом простом случае это можно сделать с помощью инструкции SELECT.   -  person OMG Ponies    schedule 17.10.2009


Ответы (5)


arrow_upward
2
arrow_downward

Вам нужно прочитать 30 млн строк из базы данных Oracle и записать 30 млн файлов из больших двоичных объектов (один заархивированный XML/текстовый файл в одном столбце BLOB на строку?) в каждой строке в файловую систему на локальном компьютере?

Очевидное решение — открыть ADO.NET DataReader на SELECT * FROM tbl WHERE <range>, чтобы вы могли делать пакеты. Считайте BLOB из считывателя в свой API, сделайте все необходимое и запишите файл. Я бы, вероятно, попытался написать программу так, чтобы она могла работать на многих компьютерах, каждый из которых выполнял бы свои собственные диапазоны - вашим узким местом, скорее всего, будет распаковка, манипуляция и повторное архивирование, поскольку многие потребители, вероятно, могут передавать данные из этой таблицы из сервер без заметного влияния на производительность сервера.

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

person Cade Roux    schedule 17.10.2009
comment
Это то, что я имел в виду изначально, я просто хотел сначала проверить с кем-то с большим опытом. Спасибо! - person JimDaniel; 17.10.2009

arrow_upward
1
arrow_downward

Моим первоначальным решением было сделать что-то вроде этого, поскольку у меня есть доступ к идентификационному номеру (псевдокод):

            int num_rows = 100;
            int base = 0;
            int ceiling = num_rows;

            select * from MY_TABLE where id >= base and id < ceiling;
            iterate through retrieved rows, do work,
            base = ceiling;
            ceiling += num_rows;
            select * from MY_TABLE where id >= base and id < ceiling;
            iterate through retrieved rows, do work,
            ...etc.

Но я чувствую, что это может быть не самый эффективный или лучший способ сделать это...

person JimDaniel    schedule 17.10.2009

arrow_upward
1
arrow_downward

Вы можете попробовать использовать запросы rownum для захвата фрагментов, пока не захватите несуществующий фрагмент.

Это хорошая статья о запросах rownum: http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html

Если вам не хочется читать, перейдите непосредственно к разделу «Разбиение на страницы с помощью ROWNUM» в конце для примера запроса.

person Jon Quarfoth    schedule 17.10.2009

arrow_upward
0
arrow_downward

Всегда предпочтительнее использовать операции на основе набора при работе с большим количеством строк.

Тогда вы получите преимущество в производительности. После обработки данных вы сможете за один раз выгрузить данные из таблицы в файл.

Жизнеспособность этого зависит от обработки, которую необходимо выполнить для строк, хотя в большинстве случаев можно избежать использования цикла. Есть ли какое-то конкретное требование, которое не позволяет вам обрабатывать все строки одновременно?

Если итерация по строкам неизбежна, может быть полезно использовать массовое связывание: массовые операции FORALL или BULK COLLECT для запросов «выбрать в».

person Jason    schedule 17.10.2009

arrow_upward
0
arrow_downward

Похоже, вам нужен весь набор данных прежде чем вы сможете выполнять какие-либо манипуляции с данными, поскольку это BLOB>. Я бы просто использовал DataAdapter.Fill, а затем передал набор данных пользовательскому объекту для итерации, выполнил его манипуляцию, а затем записал на диск конечный объект, а затем заархивировал.

person mcauthorn    schedule 17.10.2009
comment
Большой двоичный объект каждой строки представляет собой независимый ZIP-файл, который необходимо прочитать в память, обновить, затем повторно заархивировать и сохранить на локальном диске. Если это так, вы все еще рекомендуете DataAdapter.Fill? - person JimDaniel; 17.10.2009
comment
Нет, тогда я бы просто использовал DataReader, читал каждую строку, работал над этой строкой и затем переходил к следующей строке. - person mcauthorn; 18.10.2009