Використання ado і dao для масованого імпорту даних, механіка софтостроенія

Так як потужність клієнтських комп'ютерів зараз висока, то мільйони рядків в локальній БД вже
не є проблемою для обробки таких обсягів, але можуть створити вузьке місце при
інформаційному обміні.

Приватним прикладом є імпорт даних в локальну БД MS Access з віддаленого джерела. За умовами завдання необхідно максимально абстрагуватися від джерела даних. Ми заздалегідь не знаємо, яким способом користувач буде синхронізувати свою БД. Вибір MS Access в якості локальної БД також не є постулатом, незважаючи на популярність "движка" і простоту розгортання, можлива міграція в бік MS SQL Express або FireBird. Тому необхідно абстаргіроваться і від приймача.

Для MS Access найбільш очевидний варіант - використання ADO / ADO.Net, як ключовий технології доступу до даних в Windows. Менш очевидний ODBC. Ще менш "згадує" варіант - DAO, хоча він забезпечує дещо вищу швидкість при роботі з JET (MS
Access) і Excel.

adCmdTable (CommandType для Recordset-а)

Збереження записів проводилося в пакетному режимі з інтервалом в 10 тисяч записів.

Target. UpdateBatch # 40; adAffectAll # 41; ;

Результати (ви їх можете перевірити, запустивши тестовий приклад на своєму комп'ютері):
ADO
Time elapsed: 17,53 sec
Time elapsed per 1000 records: 0,04 sec

DAO
Time elapsed: 12,56 sec
Time elapsed per 1000 records: 0,03 sec

Здавалося б, якщо хочеться виграти ще кілька відсотків - беремо DAO. Але не поспішайте з висновками. Якщо крім швидкості у вас є інші критерії, то вибір стає не таким очевидним.

По-перше, швидкість ADO на практиці так само велика - десятки тисяч записів в секунду. Упевнений, в більшості випадків цього вистачить в рамках завдання.

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

доповнення

У Delphi обгортка над ADO в вигляді TCustomADODataSet і нащадків (TADOQuery, TADOTable і т.п.) має неприємну особливість - вона уповільнює навігацію по записах і полях при відносно великій їх кількості. На щастя, це проявляється лише при великих розмірах DataSet - десятки тисяч записів - і статичному курсорі на клієнті.

В такому типовому циклі обробки відбувається істотне уповільнення, причому воно поступово наростає (за спостереженнями, логарифмічно). У нашому випадку швидкість обробки не перевищувала 1000 записів в секунду. Вихід із ситуації - використовувати доступ до ADO recordset безпосередньо.

Швидкість при цьому зростає на порядок до гортання десятків тисяч записів в секунду.

Перевірив Ваш метод імпорту даних - чудово працює. Але є одне Велике АЛЕ.
Як боротися з дублікатами?
Припустимо в таблиці вже є кілька записів. По одному з полів побудований унікальний індекс.
Тепер пробуємо заімпортіровать, скажімо, 10000 записів. І серед цих записів попадається одна,
яка призведе до появи дубліката індексу.
Як скіпнуть цей запис, щоб інші 9999 вставили?

Є 2 основні рішення:

  1. перевіряти ДО вставки
  2. перевіряти ПІСЛЯ вставки

Перевірку під час операції виключаємо, тому що вона погіршить швидкість пакетної вставки.

Перевірка до вставки - це, наприклад, запит до джерела даних, в якому ви виключаєте дублікати

Перевірка після вставки (сама вставка може виявитися більш швидкої): потрібно просто видалити тимчасово ключ (обмеження цілісності або унікальний індекс), а після вставки проаналізувати записи, виключити дублікати і відтворити ключ.

Схожі статті