Експортування великої таблиці або результату запиту з однієї бази до іншої (або до файлу чи файлів типу CSV, Excel т.д.) може вимагати нестандартних підходів.
За замовчанням всі записи із таблиці-джерела розміщуються в оперативній пам'яті. В залежності від типу бази даних та використовуваного движка баз даних це стається або відразу після відкриття таблиці, або записи частинами завантажуються (fetched) з сервера і накопичуються в пам'яті локального комп'ютера впродовж експортування. І якщо у вас недостатньо RAM для розміщення всіх записів джерела, ви отримуєте помилку out of memory (нестача пам'яті), у програмі виникає збій і ви можете втратити частину експортованих даних.
Ще одна проблема може бути на цільовому боці, якщо дані експортуються до бази даних. Якщо ви вимкнете опцію Режим збереження пам'яті, експортовані записи накопичуються в оперативній пам'яті також! Але цю проблему легко виправити: просто увімкніть вказану опцію.
Тут описано два ефективних рішення, які ви можете застосувати в Database Tour.
Рішення 1. Використання живого вікна даних
Увага: Працює для баз даних, відкритих движком FD; може застосовуватися лише до таблиць, ви не можете використовувати його із запитами SQL.
Використання живого вікна даних в інтерфейсі
Рішення є легким для впровадження, але може уповільнити процес експорту. Вихідна таблиця повинна бути відкрита в режимі живого вікна даних. В цьому режимі лише невелика частина записів таблиці-джерела знаходиться в оперативній пам'яті. Після того, як ця частина експортується, пам'ять очищується і наступна частина записів завантажується.
Якщо ви бажаєте експортувати з GUI, відкрийте вашу вихідну базу даних движком FD, потім виберіть потрібну таблицю у списку таблиць. Перейдіть до закладки Дані. Далі клікніть Експорт і зробіть звичайні кроки експорту.
Використання живого вікна даних в командному рядку
Якщо ви бажаєте експортувати великі таблиці у режимі живого вікна даних з командного рядка, важливо використовувати наступні параметри:
- /SrcDBInterface=FD
- /SrcTableName=назва_вашої_таблиці
- /FetchSize=ваш_розмір_завантаження (опціонально)
Приклад командного рядка для експортування таблиці з SQLite до Oracle в режимі живого вікна даних:
dbtour.exe /export /ExportType=DATABASE /ExportMode=REPLACE+INSERT /CommitInterval=100 /MemorySaving /UseSQLParameters /UseBatchMode /FetchSize=200 /SrcDBInterface=fd /SrcDBKind=FILE /SrcDBDriver=SQLITE /SrcDB=C:\MyData\billing.db /SrcTableName=contracts /TrgDBInterface=fd /TrgDBKind=DSN /TrgDBDriver=ORACLE /TrgOSAuthentication=Yes /TrgAuthenticationMode=Normal /TrgVendorHomepath=C:\app\John\product\12.1.0\client_1 /TrgDB=dwh_prod /TrgTableName=detail.contracts
Рішення 2. Використання SQL для поділу набору даних
Рішення може бути дуже ефективним, проте воно вимагає певної підготовки. Ідея полягає в розділенні записів джерела на кілька частин і експортування їх окремо, по одній частині за раз (тобто ітеративно). Вам потрібно написати запит 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
- Відкрийте базу даних джерела.
- Клацніть кнопку Створити вікно SQL. Виконайте наступні кроки стільки разів, скільки ви запланували ітерацій.
- В редакторі SQL напишіть ваш запит SQL для поточної ітерації і клацніть кнопку Виконати запит.
- Клацніть кнопку Експорт.
- Перейдіть на закладку База даних і виберіть цільову базу даних.
- Вкажіть цільову таблицю. Ввімкніть всі доступні опції групи Режим збереження пам'яті.
- Виберіть коректний режим експорту: для першої ітерації, якщо цільова таблиця вже існує і її потрібно очистити перед експортуванням, виберіть EMPTY+INSERT; для всіх інших випадків виберіть APPEND.
- Клацніть Експорт.
Врахуйте також рекомендації по оптимізації продуктивності експорту.
Виконання з командного рядка
Вам необхідно створити окремий файл 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
Див. також