ЗОЛОТЫЕ ПРАВИЛА ОПТИМИЗАЦИИ ПРИЛОЖЕНИЙ БАЗ ДАННЫХ

Ронсаль Е.Е., Ладыженский Ю.В.
Донецкий национальный технический университет

Проблема повышения эффективности работы пользователей всегда актуальна. В докладе изложены на примере СУБД InterBase типичные проблемы, которые замедляют работу приложений, и правила, которых следует придерживаться, чтобы приложение работало максимально эффективно.

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

Рекомендуется разрабатывать приложение в условиях максимально приближенным к тем, в которых будет находиться конечный пользователь. Это означает, во-первых, использование базы данных, заполненной реальными данными. Во-вторых, использование удаленного сервера баз данных (локальное соединение будет маскировать задержки в сети). И в-третьих, рекомендуется работать в системе с правами пользователя, а не администратора, что позволит обнаружить проблемы с производительностью, вызванные ограничениями безопасности [1].

Реализация приведенных ниже шагов на этапе проектирования позволит избежать многих типичных проблем с производительностью системы:

1. Выбор стратегии доступа к данным.

Многозвенная архитектура решает проблемы масштабируемости, поэтому она должна использоваться во всех приложениях, за исключением самых простейших. Многозвенные системы должны изначально разрабатываться так, чтобы они никогда не запрашивали большие объемы данных (это требование должно строго соблюдаться в системах, где сервер приложений не сохраняет состояния – stateless application server). В двухзвенных системах таких жестких ограничений не существует.

2. Выбор компонентов доступа к данным.

Следует принять решение о том, какие компоненты для доступа к данным использовать: независимые от типа СУБД или адаптированные для работы с определенным типом СУБД (например, компоненты InterBase Express - IBX). Если в процессе эксплуатации системы не ожидается замены сервера БД, то лучше использовать специфические компоненты (IBX), так как они позволяют достичь значительно лучшей производительности.

3. Создание эффективных запросов к базе данных.

3.1. Минимизация объемов данных, передаваемых по сети. Прежде всего следует запрашивать меньше данных (не использовать оператор '*' в запросах на выборку, перечислять поля явно; продумать пользовательский интерфейс так, чтобы не было необходимости возвращать пользователю все записи таблицы, предоставив ему средства для поиска; предпочтительно выполнять объединение таблиц (операторы WHERE, JOIN) вместо lookup-полей).

3.2. Выполнение подготовки запросов (метод Prepare()).

3.3. Отказ от использования вложенных подзапросов [2].

3.4. Отказ от использования итераций по наборам данных.

Работа в многопользовательской среде делает сложным подсчет записей, поэтому желательно не использовать свойство RecordCount и агрегатную функцию SQL COUNT. Также следует избегать итераций по результирующему набору, поскольку это означает пересылку большого объема данных между клиентом и сервером. Процесс значительно ускорится, если эти операции выполнять на сервере.

4. Правильное использование механизма транзакций.

4.1. Определение уровней изоляции.

Следует разделить все запросы на группы и для каждой группы использовать транзакции с определенными параметрами (уровнем изоляции, режимом доступа). Например, для запросов на чтение самых последних изменений в базе данных установить уровень изоляции транзакции read committed, а для запросов на чтение данных для построения отчета - уровень изоляции snapshot [3]. Установление транзакции в режим только для чтения (Read-Only) позволяет указать цель использования транзакции, в некоторых случаях это позволяет серверу провести внутреннюю оптимизацию.

4.2. Рациональное завершение транзакций.

Существует два способа завершения транзакций: подтверждение (Commit) и откат (Rollback). Откат следует делать только тогда, когда это действительно необходимо, в остальных случаях – подтверждать, так как количество откатов учитывается сервером для определения момента времени очистки базы данных. Транзакции с долгим временем жизни способны значительно повысить загрузку сервера, следовательно, при планировании проекта следует обращать внимание на то, чтобы транзакция не оставалась активной дольше, чем существует запрос (поэтому нужно с осторожностью использовать одну транзакцию для нескольких запросов). Нежелательно использовать Commit/Rollback Retaining, так как они не завершают транзакцию. Транзакции предпочтительнее завершать, даже если их немедленно придется перезапустить, так как это уменьшает время жизни транзакции.

4.3. Очистка базы данных (сборка мусора). Существует несколько способов решения проблем с производительностью, связанных со сборкой мусора: во-первых, запретить автоматическую очистку базы данных и запускать ее вручную в период наименьшей загруженности сервера, во-вторых, использовать транзакции в режиме read committed вместо snapshot и, по возможности, избегать откатов.

Если необходимо оптимизировать готовое приложение, то прежде всего следует выявить узкие места в системе, то есть главные причины снижения производительности и только после этого приступать к оптимизации. Для выявления узких мест возможно использование специальных инструментальных средств (например, SQL-монитор, профайлер кода).

Следование рассмотренным выше принципам поможет разработчику в создании качественных приложений.

Литература
1. Optimization I: Optimizing InterBase Applications, by Craig Stuntz, 2003
(http://bdn.borland.com/borcon2004/article/paper/0,1963,32255,00.html).
2. Оптимизация приложений С++Builder в архитектуре клиент/сервер, Наталия Елманова, Центр информационных технологий
(http://www.citforum.ru/programming/cpp/cb_498.shtml).
3. А. Н. Ковязин, С.М. Востриков "Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/Firebird/Yaffil (3-е издание)" - М.: Кудиц-образ, 2005.