DB Stressor. Испытываем производительность БД

О программе

DB Stressor - это инструмент, позволяющий провести испытания ваших баз данных на производительность и устойчивость при многопользовательской работе. Единственным требованием к СУБД является наличие ODBC или OLE DB-драйвера и возможность исполнять сценарии (SQL-скриптов) на собственном расширенном подмножестве SQL и/или его процедурном расширении. Практически все широко распространенные СУБД обладают такими возможностями, например: MSSQL и Sybase ASE (Transact-SQL), Oracle (PL/SQL), InterBase (процедурное расширение), Sybase SQL Anywhere (Watcom-SQL) и многие другие.

Для проведения испытаний нужно спланировать порядок и определить содержание тестов, а затем создать на этой основе сценарий поведения пользователей на языке вашей СУБД, возможно, с использованием нескольких поддерживаемых DB Stressor-ом полезных макросов. DB Stressor эмулирует многопользовательскую работу, собирает и запоминает статистику выполнения вашего сценария и представляет результаты в обработанном виде.

Установка

  1. Загрузите и установите пакет Microsoft Data Access Components (MDAC) version 2.7 или выше если он еще не установлен у вас на ПК
  2. По ссылке в конце страницы загрузите дистрибутивный комплект. Распакуйте DBStressor в отдельный каталог на вашем ПК (рекомендуем создать его)
  3. Запустите bin\DBStressor.exe

Планируем тесты

Основными целями тестов могут являться измерения производительности и времени отклика СУБД при:

  • различных аппаратных конфигурациях сервера БД
  • различном числе пользователей

В общем случае, для проведения тестов вам необходимо:

  • определить исходные данные для тестов:
    • количественный состав конечных пользователей, их роли и типовые сценарии работы в системе
    • временные характеристики типовых сценариев конечных пользователей
  • разработать типовые сценарии конечных пользователей на языке вашей СУБД
  • провести тесты
  • проанализировать результаты

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

Пример разработки теста

Определение исходных данных

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

Вам также должен быть известен состав пользователей: их роли и типовые сценарии работы в системе. Например, пусть 15 человек из 100 будут являться операторами, которые вносят информацию в базу данных, 3 человека - корректоры и эксперты, которые выборочно проверяют внесенную информацию, исправляют ошибки или удаляют дезинформацию, и 82 человека - читатели, которые производят поиск, выборки и группировки с несложными расчетами (общее количество, среднее и т.д.) по всей базе данных с использованием различных критериев. Несколько упрощенная картина для информационно-поисковой системы подразделения какой-нибудь госслужбы.

Согласно типовым сценариям, один оператор вносит единицу информации (например, документ) в среднем 15 раз в час. Корректор за тот же час меняют содержание 15 документов и удаляет 5 (итого: 20). Читатель делает за час в среднем 30 запросов из которых 25 - линейный поиск по атрибутам, а 5 - расчеты и группировки. Из этих цифр легко получить средние значения времени пауз (задержек) между операциями пользователей.

Кроме этого нам нужно определить и нижние ограничения, связанные с физическими возможностями пользователей. В нашем примере оператор не может создать новый документ быстрее, чем за 1 минуту, корректор - проверить документ менее, чем за 2 минуты, а читатель - ввести новый запрос менее, чем за 20 секунд. Теперь, имея средние и нижние значения, мы можем вычислить и верхние, как сумму нижнего и удвоенного среднего значений:

Dmax = Dmin + 2 * Davg (1)

Так как для DBStressor необходимы только нижняя и верхняя оценки, поэтому если в вашем примере они будут известны изначально, то средние значения можно не вычислять.

Исходя из вышеназванных предположений, мы получаем следующие начальные условия для создания сценария (исходные временные параметры для DBStressor задаются в миллисекундах):

Тип пользователей Количество пользователей данного типа Среднее число операций в единицу времени Время задержки между операциями
Среднее (Davg) Минимальное (Dmin) Максимальное (Dmax)
Операторы 15 15 операций в час 4 мин (240 000 мсек.) 20 сек (20 000 мсек.) 500 000 мсек.
Корректоры 5 20 операций в час 3 мин (180 000 мсек.) 30 сек (30 000 мсек.) 390 000 мсек.
Читатели 80 30 операций в час 2 мин (120 000 мсек.) 20 сек (20 000 мсек.) 260 000 мсек.

Здесь следует отметить, что при использовании многозвенной архитектуры и мультиплексирования ничего принципиально не меняется - вас интересует производительность СУБД. В этом случае DBStressor должен будет эмулировать работу по сценариям, написанным для сервера приложений, являющегося непосредственным клиентом СУБД. Для расчета можно воспользоваться следующими простыми формулами:

K = U / Cas (2)
Ui as = Ui / K (3)
Di as = Di * K (4)

где

К - коэффициент мультиплексирования
U - общее количество конечных пользователей
Cas - число соединений сервера приложений к СУБД (если оно меняется, например, в зависимости от нагрузки, то воспользуйтесь средней величиной)
Ui - количество конечных пользователей i-го типа
Ui as - количество пользователей i-го типа с учётом мультиплексирования сервером приложений
Di - время задержки между операциями конечного пользователя i-го типа
Di as - время задержки между операциями конечного пользователя i-го типа с учётом мультиплексирования

При этом мы делаем важное допущение, что данные на уровне сервера приложений не кэшируются, поскольку это должно только увеличивать производительность. Если когда-нибудь вдруг окажется, что производительность при использовании кэширования будет ниже, показанной на тестах - выбросите такое кэширование в мусорную корзину :).

Разрабатываем сценарии

Для простоты примера, примем следующую схему базы данных, состоящую всего из двух таблиц ("Заголовки Документов" и "Строки Документов") с которыми будут взаимодействовать наши пользователи. Сценарии при таких начальных условиях будут достаточно простыми. Их запись на Transact-SQL для СУБД MS SQL 2000 приведена в Приложении 1.

Проводим тесты

Запустите DBStressor, закладка "Test settings" (установки тестирования) станет видимой.

Определите строку соединения ADO к вашей СУБД. Это легко можно сделать, используя построитель (кнопка "Build")

Параметры вывода информации (Output options) позволяют управлять отображением выходных данных тестирования. В поле "Refresh interval" задается интервал обновления данных тестирования в секундах. Окно вывода сообщения (Messages log) будет показывать только последние N строк, где N задается в поле "Log display only". Объем выводимой информации регулируется значением в поле "Messages level" от 0 (минимум сообщений) до 4 (максимально подробные сообщения). Все сообщения могут также записываться в файл, если вы включите опцию "Save log to file" и зададите его название и путь.

Группа параметров "Stop conditions" позволяет задать условия окончания тестирования. Доступны условия:

  • по достижению заданного числа ошибок
  • по количеству выполненных "пользователями" пакетов (сценариев)
  • в заданное время
  • после прохождения заданного интервала времени

Замечание: DBStressor не может остановиться немедленно, даже если задано точное время. В этом случае программа ожидает окончания выполнения "пользователями" пакета и после этого останавливается.

После установки параметров тестирования перейдите на закладку "Scenario parameters" (параметры сценариев) чтобы задать типы (роли) пользователей, их число и задержки между выполнением пакетов.

Теперь вы готовы запустить тест. Нажмите кнопку "Start" или комбинацию клавиш "Ctrl+S". Программа запустит тесты и перейдет на закладку "Test results" (результаты).

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

После окончания тестирования вы можете экспортировать результаты в MS Excel (для этого у вас должен быть установлен на компьютере MS Office версии 2000 или выше), чтобы произвести дополнительную обработку результатов.

Список поддерживаемых макросов

%UserNumber% подставляет номер пользовательского процесса - целое число в диапазоне
0 <= UserNumber < Total amount of users - 1
%Random()% подставляет 15-разрядное случайное число в диапазоне 0 <= X < 1
%Random(N)% подставляет целое случайное число в диапазоне 0 <= X < N
%Delay(N)% является окончанием части сценария (т.е. все декларации выше макроса не будут видны в частях ниже его) и прерывает выполнение на N миллисекунд
%DelayRandom(N)% то же самое, но задержка выбирается случайным образом из диапазона 0 <= X < N

Приложение 1

Схема БД

/*
  DBStressor sample script for MS SQL 2000
  uses PUBS database to create tables
*/
use pubs
go
 
create table DocumentHeaders (
  Number int not null identity(1, 1),
  Name varchar(128) not null,
  DocDate datetime not null,
  constraint PK_DocumentHeaders primary key (Number)
)
go
create index IX_Name_DocumentHeaders on DocumentHeaders(Name)
go
 
create table DocumentLines (
  DocNumber&nbsp;&nbsp; int not null,
  LineNumber&nbsp; int not null,
  LineText&nbsp;&nbsp;&nbsp; varchar(255),
  constraint PK_DocumentLines primary key (DocNumber, LineNumber),
  constraint FK_DocumentLines_DocumentHeaders
    foreign key (DocNumber) references DocumentHeaders(Number)
)
go
create index IX_LineText_DocumentLines on DocumentLines(LineText)
go

Сценарий для Оператора

/*
  DBStressor sample script for MS SQL 2000
*/
/* Operator actions scenario */
use pubs
declare @DocNumber int
-- insert document header
-- inserting current date and time value
insert into DocumentHeaders(DocDate, Name)
  values (getdate(), 'Doc %Random(100)%')
-- getting last value of autoincrement column
select @DocNumber = @@identity
-- insert random count of document lines from a range of 30 < @Count < 80
declare @Count int, @i integer
set @Count = 30 + %Random(50)%
set @i = 1
while @i <= @Count begin
  insert into DocumentLines(DocNumber, LineNumber, LineText)
    values (@DocNumber, @i, 'Line %Random(1000000)% text %Random(1000000)% text2 %Random(1000000)%')
  set @i = @i + 1
end

Сценарий для Корректора

/*
  DBStressor sample script for MS SQL 2000
*/
 
/* Editor actions scenario */
 
use pubs
 
-- select random document
declare @DocNumber      int,
        @MaxDocNumber   int,
        @LineNumber     int,
        @MaxLineNumber  int
 
select @MaxDocNumber = max(Number) from DocumentHeaders
select @DocNumber = @MaxDocNumber * %Random()%
-- select nearest existing document
select top 1 @DocNumber = Number from DocumentHeaders
  where Number >= @DocNumber
  order by Number Asc
if @@rowcount = 0 begin
  select top 1 @DocNumber = Number from DocumentHeaders
    where Number <= @DocNumber
    order by Number Desc
end
 
if %Random(20)% < 15 begin
  select @MaxLineNumber = count(*) from DocumentLines where DocNumber = @DocNumber
  select @LineNumber = @MaxLineNumber * %Random()%
  update DocumentLines
    set LineText = 'Line %Random(1000000)% corrected %Random(1000000)% corrected2 %Random(1000000)%'
    where DocNumber = @DocNumber and LineNumber = @LineNumber
end
else begin
  begin transaction
  delete from DocumentLines where DocNumber = @DocNumber
  delete from DocumentHeaders where Number = @DocNumber
  commit
end

Сценарий для Читателя

/*
  DBStressor sample script for MS SQL 2000
*/
 
/* Reader actions scenario */
use pubs
 
-- select random document
if %Random(30)% < 25 begin
  select *
    from DocumentHeaders DH join DocumentLines DL on DH.Number = DL.DocNumber
    where datediff(ss, DH.DocDate, getdate()) > %Random(3600)% and
    DL.LineText like '%%Random(1000000)%%'
end
else begin
  select count(*)
    from DocumentHeaders DH join DocumentLines DL on DH.Number = DL.DocNumber
    where DL.LineText like '%%Random(1000000)%%'
end
Прикрепленный файлРазмер
Package icon DBStressor.zip703.8 KB