Документація Database Tour Contents Index

Експорт великих наборів даних

Top Previous Next

Експортування великої таблиці або результату запиту з однієї бази до іншої може вимагати нестандартних підходів.

За замовчанням всі записи із таблиці-джерела розміщуються в оперативній пам'яті. В залежності від типу бази даних та використовуваного движка баз даних це стається або відразу після відкриття таблиці, або записи частинами приносяться (fetched) з сервера і накопичуються в пам'яті локального комп'ютера впродовж експортування. І якщо у вас недостатньо RAM для розміщення всіх записів джерела, ви отримуєте помилку out of memory (нестача пам'яті), у програмі виникає збій і ви можете втратити частину експортованих даних.

Ще одна проблема може бути на цільовому боці. Якщо ви вимкнете опцію Режим збереження пам'яті, експортовані записи накопичуються в оперативній пам'яті також! Але цю проблемо легко виправити: просто ввімкніть вказану опцію.

Рішення

Рішення може бути дуже ефективним, проте воно вимагає певної підготовки. Ідея полягає в розділенні записів джерела на кілька частин і експортування їх окремо, по одній частині за раз (тобто ітеративно). Вам потрібно написати запит SQL для кожної ітерації. Цим способом можна експортувати і таблиці, і навіть результати складних запитів SQL.

Ключовий момент - як саме ділити записи. Рекомендується використовувати первинний ключ, тобто використовувати умову фільтру, що базується на значеннях в полі чи полях, що відносяться до первинного ключа таблиці, наприклад:

/*1-а ітерація*/ SELECT * FROM MyTable WHERE Id BETWEEN 0 AND 10000;
/*2-а ітерація*/ SELECT * FROM MyTable WHERE Id BETWEEN 10001 AND 20000;
/*3-я ітерація*/ SELECT * FROM MyTable WHERE Id BETWEEN 20001 AND 30000;

і т.д.

Якщо первинного ключа немає або експортується результат складного запиту, спробуйте використати іншу умову фільтру, яка ефективно відбере різні частини записів джерела:

/*1-а ітерація*/ SELECT * FROM MyTable WHERE ClientName LIKE 'A%';
/*2-а ітерація*/ SELECT * FROM MyTable WHERE ClientName LIKE 'B%';
/*3-я ітерація*/ SELECT * FROM MyTable WHERE ClientName LIKE 'C%';

і т.д. Врахуйте індекси і т.і.

Деякі бази даних (наприклад, Oracle, SQL Server, PostgreSQL та інші) дозволяють ефективно розділити записи джерела по внутрішнім ідентифікаторам записів. Ось як це можна зробити в базі даних SQL Server:

/*1-а ітерація*/ SELECT * FROM MyTable ORDER BY SomeColumn OFFSET 0 ROWS FETCH NEXT 2000000 ROWS ONLY;
/*2-а ітерація*/ SELECT * FROM MyTable ORDER BY SomeColumn OFFSET 2000000 ROWS FETCH NEXT 2000000 ROWS ONLY;
/*3-я ітерація*/ SELECT * FROM MyTable ORDER BY SomeColumn OFFSET 4000000 ROWS FETCH NEXT 2000000 ROWS ONLY;

і т.д.

Важливо: Для цільової частини в 2-й та подальших ітераціях не забудьте вказати APPEND в якості режима експорту. Він дозволяє додавати нові записи до існуючої цільової таблиці.

Виконання з GUI

  1. Відкрийте базу даних джерела.
  2. Клацніть кнопку Створити вікно SQL. Виконайте наступні кроки стільки разів, скільки ви запланували ітерацій.
    1. В редакторі SQL напишіть ваш запит SQL для поточної ітерації і клацніть кнопку Виконати запит.
    2. Клацніть кнопку Експорт.
    3. Перейдіть на закладку База даних і виберіть цільову базу даних.
    4. Вкажіть цільову таблицю. Ввімкніть опцію Режим збереження пам'яті.
    5. Виберіть коректний режим експорту: для першої ітерації, якщо цільова таблиця вже існує і її потрібно очистити перед експортуванням, виберіть EMPTY+INSERT; для всіх інших випадків виберіть APPEND.
    6. Клацніть Експорт.

Виконання з командного рядка

Вам необхідно створити окремий файл SQL та окремий командний рядок для кожної експортної ітерації. Отже, створіть файли SQL з коректними запитами для кожної ітерації і назвіть їх, наприклад, MyQuery1.sql, MyQuery2.sql, і т.д., у відповідності до номерів ітерацій.

Ви можете сконструювати командний рядок або вручну, використовуючи специфікацію з документації, або за кілька кліків з GUI. В останньому випадку виберіть Інструменти | Генерація командного рядка | Експорт / Імпорт даних.... Збережіть отриманий командний рядок, наприклад, до файлу типу .bat.

Далі повторіть це для кожної ітерації. Або просто скопіюйте даний командний рядок стільки разів, скільки у вас буде ітерацій; в кожному скопійованому командному рядку замініть назву файлу SQL коректним шляхом для потрібної ітерації та вкажіть коректний режим експорту, як описано вище. Запишіть створені командні рядки до файлу .bat і запустіть ваш процес експорту.

Пам'ятайте, що ви також можете створювати командні рядки у вигляді файлів операцій, один файл операцій на ітерацію. Нижче наведено приклади файлів операцій для експорту великої таблиці із бази PostgreSQL до бази Firebird:

;1-а ітерація
/export
/ExportType=DATABASE
;для 1-ї ітерації, якщо існуючу цільову таблицю потрібно очистити, використовуйте режим експорту EMPTY+INSERT
;в інших випадках використовуйте режим експорту APPEND
/ExportMode=EMPTY+INSERT
/CommitInterval=1000
/MemorySaving
/UseSQLParameters
/UseBatchMode
;джерело:
/SrcDBInterface=fd
/SrcDBKind=DSN
/SrcDBDriver=POSTGRESQL
/SrcDB=clients
/SrcServer=MyPgServer
/SrcPort=5432
/SrcVendorLibrary=C:\Program Files (x86)\PostgreSQL\9.6\bin\libpq.dll
/SrcSQLFile=c:\MyExportFiles\Postgres-to-Firebird\Iteration1.sql
;ціль:
/TrgDBInterface=fd
/TrgDBKind=FILE
/TrgDBDriver=Firebird
/TrgDBUserName=sysdba
/TrgPort=3050
/TrgProtocol=TCPIP
/TrgOSAuthentication=No
/TrgVendorLibrary=C:\Program Files (x86)\Firebird\Firebird_3_0\fbclient.dll
/TrgDB=C:\My Firebird database\CLIENTS.FDB
/TrgTableName=MyTable
;2-а ітерація
/export
/ExportType=DATABASE
;для 2-ї та подальших ітерацій використовуйте режим експорту APPEND
/ExportMode=APPEND
/CommitInterval=1000
/MemorySaving
/UseSQLParameters
/UseBatchMode
;джерело:
/SrcDBInterface=fd
/SrcDBKind=DSN
/SrcDBDriver=POSTGRESQL
/SrcDB=clients
/SrcServer=MyPgServer
/SrcPort=5432
/SrcVendorLibrary=C:\Program Files (x86)\PostgreSQL\9.6\bin\libpq.dll
/SrcSQLFile=c:\MyExportFiles\Postgres-to-Firebird\Iteration2.sql
;ціль:
/TrgDBInterface=fd
/TrgDBKind=FILE
/TrgDBDriver=Firebird
/TrgDBUserName=sysdba
/TrgPort=3050
/TrgProtocol=TCPIP
/TrgOSAuthentication=No
/TrgVendorLibrary=C:\Program Files (x86)\Firebird\Firebird_3_0\fbclient.dll
/TrgDB=C:\My Firebird database\CLIENTS.FDB
/TrgTableName=MyTable
...
;N-а ітерація
/export
/ExportType=DATABASE
;для 2-ї та подальших ітерацій використовуйте режим експорту APPEND
/ExportMode=APPEND
/CommitInterval=1000
/MemorySaving
/UseSQLParameters
/UseBatchMode
;джерело:
/SrcDBInterface=fd
/SrcDBKind=DSN
/SrcDBDriver=POSTGRESQL
/SrcDB=clients
/SrcServer=MyPgServer
/SrcPort=5432
/SrcVendorLibrary=C:\Program Files (x86)\PostgreSQL\9.6\bin\libpq.dll
/SrcSQLFile=c:\MyExportFiles\Postgres-to-Firebird\IterationN.sql
;ціль:
/TrgDBInterface=fd
/TrgDBKind=FILE
/TrgDBDriver=Firebird
/TrgDBUserName=sysdba
/TrgPort=3050
/TrgProtocol=TCPIP
/TrgOSAuthentication=No
/TrgVendorLibrary=C:\Program Files (x86)\Firebird\Firebird_3_0\fbclient.dll
/TrgDB=C:\My Firebird database\CLIENTS.FDB
/TrgTableName=MyTable

А ваш файл .bat повинен виглядати приблизно так:

REM 1-а ітерація
"C:\Program Files (x86)\Vitaliy Levchenko\Database Tour Pro 9\dbtour.exe" /ActionFile=C:\MyExportFiles\Postgres-to-Firebird\Action1.txt
REM 2-а ітерація
"C:\Program Files (x86)\Vitaliy Levchenko\Database Tour Pro 9\dbtour.exe" /ActionFile=C:\MyExportFiles\Postgres-to-Firebird\Action2.txt
...
REM N-а ітерація
"C:\Program Files (x86)\Vitaliy Levchenko\Database Tour Pro 9\dbtour.exe" /ActionFile=C:\MyExportFiles\Postgres-to-Firebird\ActionN.txt