магістр Мартіросова К.В.

Національний гірничий університет, Україна

Методика створення правдоподібних даних на етапі тестування продуктивності баз даних.

 

Серед важливих етапів тестування баз даних (БД) генерування тестових даних є, ймовірно, самим недооцінюваним. Історії процесу тестування БД відомі такі випадки, коли генерування якісних даних займало значно більше часу, ніж виправлення і тестування операцій SQL. Проблема з SQL полягає в тому, що яким не був код, запит до таблиці з десяти рядків завжди буде виконуватися миттєво, а в більшості випадків ми маємо можливість побачити результат на екрані відразу після того, як натиснемо клавішу Enter, іноді навіть у випадку таблиці з 10 000 рядків. Падіння продуктивності зазвичай починається тільки після накопичення  достатньої кількості даних. На цьому етапі  виникає потреба у тестових даних. Хоч й у більшості випадків можна порівняти відносну продуктивність альтернативних варіантів з таблицями середнього розміру, досить важко передбачити, чи зумієте ви домогтися прийнятної продуктивності без повторного тестування цільових обсягів.

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

Одним з засобів отримання тестових даних є розмноження рядків. Тобто, ми маємо таблицю відомостей про робітників компанії emp, яка містить, 14 рядків. За допомогою створення допоміжної таблиці або уявлення (view) ten_rows, при запиті до якого будуть  повернуті  значення від 0 до 9 як стовпець num, та декартового добутку можемо додати до таблиці emp 56 000 нових рядків (14 рядків х 10 х 10 х 10 х 4), виконавши наступний фрагмент коду:

insert into emp select e.* from emp e,

ten_rows t1,

ten_rows t2,

ten_rows t3,

(select num from ten_rows

where num < 4) t4

 

Але на цьому етапі виникне проблема с первинним ключем, оскільки кожен з ідентифікаторів співробітників, які за своєю суттю є унікальними, повинен бути розмножений 4000 разів.  Є два рішення цієї проблеми: видалити всі унікальні індекси, що реалізують обмеження, розмножити дані, а потім знову повернути обмеження або спробувати сгенерувати випадкові значення в процесі вставки. Обмеження первинного ключа буде витримано, але дані ви отримаєте сумнівні, бо якщо ви будете множити стовпці, то отримаєте тільки 14 різних імен для більш ніж 50 000 співробітників та 14 дат прийому на работу, що не має ніякого відношення до реальності (тільки уявіть, 4000 людей, які були прийняті на роботу в один день – це неможливо).

Цей засіб не можна назвати поганим, та не слід забувати, що нам дані потрібні для тестування продуктивності БД, а для отримання реальних вимірів продуктивності знадобляться саме правдоподібні тестові дані.

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

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

select job, count(*) from emp

group by job;

 

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

CLERK    4

SALESMAN 4

PRESIDENT 1

MANAGER  3

ANALYST  2

 

Звичайно, якщо б таблиця emp містила набагато більше рядків ніж 14, результат виконання цього запиту був би більш показовим та його можна було б використати як основу розподілу тестових даних. Тому, опираючись на отриманий результат, визначимось с розподілом спеціальностей (за виключенням посаду президента, один рядок м зможемо пізніше вставити вручну) таким чином: MANAGER – 20%, CLERK – 35%, SALESMAN – 35%, ANALYST – 10%. Створення такого розподілу буде нескладним, якщо ми пов'яжемо кожну назву посади з інтервалом значень між 0 та 100. Тобто, нашою задачею стає генерація випадкових чисел рівномірно розподілених у цьому інтервалі. Якщо число потрапить у діапазон від 0 до 35, буде повернено значення CLERK; якщо воно потрапить у діапазон від 35 до 70, буде повернено значення SALESMAN; від 70 до 80 – ANALYST та від 80 до 100 – MANAGER.

Ви можете застосувати ці прийоми для генерування даних майже будь-якого типу. Все, що вам потрібно – знайти списки елементів для яких зазначені вагові коефіцієнти (іноді ви можете знайти ранги, але можна створити вагові коефіцієнти, призначивши більшу вагу першому рангу, 0.8 від цієї ваги – другому рангу, 0.8 від останньої ваги – третьому рангу, і т.д.). Зрозуміло, що будь-яка інструкція group by до існуючих даних дозволить вам заповнити тестові дані у відповідності з існуючими співвідношеннями.

Висновок

         На етапі тестування БД перед розробником встає задача створення тестових даних для заповнення бази, бо частіше за все права на використання реальних даних відсутні або з інших причин розробник не може отримати дані. Розглядаючи різні варіанти вирішення цієї задачі було з'ясовано, що задля тестування продуктивності БД слід створювати правдоподібні та адекватні дані, тобто дані схожі на реальні. У цій статті було запропоновано методику створення саме правдоподібних даних.

 

Перелік літератури:

1.       Стефан Фаро, Паскаль Лерми, «Рефакторинг SQL-приложений», // изд. Символ, — 2009.

2.       Деннис Шаша, Филипп Боне, «Оптимизация баз данных. Принципы, практика, решение проблем», // изд. КУДИЦ-Образ,  — 2004.

3.     K. Houkjaer, K. Torp, and R. Wind. «Simple and Realistic Data Generation» Proceedings on Very Large Data Bases, — 2006.

4.     Joseph E. Hoag, Craig W. Thompson, «Synthetic Data Generator», http://www.sigmod.org/publications/sigmod-record/0703/06.article-hoag.pdf, — 2008.

5.     N. Bruno, S. Chaudhuri, «Flexible Database Generators», Proceedings on Very Large Data Bases, — 2005.