А Ковязин - Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Производительность
Производительность систем на базе СУБД является одним из ключевых факторов при выборе сервера. Учитывая это, при разработке сервера Yaffil большое внимание уделяется оптимизации исходного кода, используются средства анализа и профайлинга производительности.
Надежность и безопасность
В сервере Yaffil исправлено большое число критических ошибок, многие из которых приводят к порче данных. В предыдущих версиях InterBase такие опасные ситуации, как порча памяти (вследствие ошибки в коде сервера, некорректной UDF или испорченных метаданных БД), протекали внешне незаметно до тех пор. пока база данных не была непоправимо испорчена.
Ошибка при работе с памятью в Yaffil, как правило, приводит к немедленному останову сервера с потерей только последних обновляющих транзакций.
В Yaffil, как и в InterBase 7.0, исправлена дыра в безопасности, связанная с использованием внешних таблиц для получения доступа к любому файлу системы. Также в Yaffil исправлена серьезная ошибка, связанная с обработкой структурированных исключений (SEH) Win32 API
Отличительные особенности сервера Yaffil
Улучшенная производительность
Производительность является одним из ключевых факторов, определяющих пригодность сервера СУБД для использования в конкретном приложении. Производительность определяет максимальную нагрузку, которую сервер может нести на выбранной аппаратной платформе, выраженную, например, в количестве одновременно работающих пользователей или количестве операций, выполняемых в единицу времени. К сожалению, скоростные характеристики линейки серверов InterBase часто уступают показателям конкурентов, таких, как MSSQL или Sybase SQL Anywhere. По производительности Yaffil далеко опережает своих аналогов из клона InterBase. При выполнении тех же самых запросов Yaffil работает в 2-3 раза быстрее, чем InterBase 6.0 и Firebird 1.0. Такие результаты достигнуты благодаря многочисленным улучшениям алгоритмов и оптимизацией кода, большое число критических алгоритмов переписаны на ассемблере х86 убраны ненужные системные вызовы
Улучшенный оптимизатор запросов
Оптимизатор - своего рода "мозг" сервера, и степень его интеллектуальности может кардинально повлиять на скорость работы приложений. Неверно выбранный план может привести к увеличению времени выполнения запроса в тысячи раз. За время своей эволюции от версии InterBase 4.0, не способной вообще оптимизировать явные соединения, и до последних версий в оптимизатор InterBase разработчиками Borland вносились изменения, которые хотя и приводили к улучшению планов для определенных случаев, но часто непредсказуемо сказывались на других запросах. Например, в пятой версии InterBase научился корректно оптимизировать соединения в явном синтаксисе ANSI SQL, но другой способ выборки индексов в ряде случаев приводил к катастрофическому увеличению времени выполнения запросов. Подобные неприятности появились в версии 6.0, в результате многие разработчики не могли перенести свои системы на современную платформу.
Проанализировав большое число проблемных случаев с оптимизацией InterBase версий 4.x, 5.x и 6.x, разработчики Yaffil внесли ряд улучшений, в результате чего в большинстве случаев можно вообще отказаться от применения ручных планов При этом при переходе на Yaffil со старых версий InterBase случаев ухудшения автоматических планов практически не наблюдается.
Однако в тех случаях, когда ручного планирования не избежать, Yaffil предоставляет больше возможностей для этого.
Перечислим некоторые улучшения оптимизатора Yaffil.
Выбор индекса с меньшим числом полей при наличии индекса с большим числом полей
Этот случай часто возникает, когда в таблице имеется большое количество индексов, в том числе составных. Оптимизатор Interbase/Firebird всегда пытался выбрать индекс, который охватывает множество полей, в то время как существовал более быстрый и компактный индекс. Оптимизатор Yaffil автоматически разрешает данную ситуацию. Вот пример: Таблица из трех полей Table 1 (Fl, F2, F3) На нее созданы три индекса: IDX_F1(F1), IDX_F1_F2(F1,F2), IDX_F1_F2_F3(F1,F2,F3) Выполняем запрос:
select * from Tablel where Fl = параметр
Получаем следующие планы для использования индексов: Interbase 6.5/FireBird 1.0:
PLAN (Т INDEX (IDX_F1_F2_F3))
Yaffil:
PLAN (T INDEX (IDX_F1))
Interbase 6.5/FireBird 1.0 используют индекс с максимальным количеством полей, хотя очевидно, что в данном случае надо использовать единственный индекс по полю F1, как это и делает Yaffil. Это очень распространенная ошибка, приводящая к замедлению выполнения запроса, обойти которую без явного планирования достаточно сложно.
Возможность использовать индекс с начальными сегментами, удовлетворяющими условию и сортировкой по остальным
Этот случай возникает, когда выборка делается по одному полю, а сортировка - по другому, при этом имеется индекс по обоим полям. Пример: пусть существует таблица из трех полей T(F1,F2,F3), есть индексы на следующие сочетания полей: на одно поле IDX_F1(F1), на два первых поля IDX_F1_F2(F1,F2), на все три поля IDX_F1_F2_F3(F1,F2,F3).
Производим запрос следующего вида:
select * from T where Fl=.. order by F2
Получаем планы следующего вида:
FireBird/InterBase 6.5:
PLAN SORT(Т INDEX (IDX_F1_F2_F3))
Yaffil:
PLAN (T ORDER (IDX_F1))
Исключение из обработки индексов с сильно различающейся селективностью
Пример: пусть у нас есть таблица из трех полей T(F1,F2,F3) с индексами на каждое поле IDX_Fl(Fl), IDX_F2(F2) и IDX_F3(F1). Пусть здесь F1 является уникальным полем (первичный ключ, например), a F2 - неуникальным. Производим запрос:
select * from Т where Fl = параметр! and F2 = параметр2 ...
В результате получаем следующие планы: FireBird/InterBase 6.5:
PLAN (Т INDEX (IDX_F1, IDX_F2))
Yaffil:
PLAN (Т INDEX (IDX_F1))
Оптимизатор Yaffil всегда объединяет индексы с учетом селективности.
Отметим, что в качестве критериев отбора индексов используется не только селективность, но и категории условий, используемых в ограничениях. Так, например, "вес" операции "=" больше, чем "вес" операций "<" и ">".
Оптимизация сетевого трафика
Как правило, сервер СУБД устанавливается не на одном компьютере вместе с клиентом, а используется через локальную сеть. При этом на времени отклика сервера сказываются задержки при передаче данных по сети, независимо от того, насколько мощный сервер установлен.
Объем сетевого трафика Yaffil значительно уменьшен за счет более эффективной передачи полей типа VARCHAR, так как передаются данные фактической длины, а не объявленной в описании типа. Аналогичное улучшение есть в Borland InterBase, начиная с версии 6.5.
Эффективная работа с временными файлами сортировки
В сервере InterBase сортировка всегда выполняется с использованием временных файлов, независимо от количества доступной памяти. Операции чтения/записи временных файлов дополнительно нагружают дисковую подсистему, что может отрицательно сказаться на скорости работы сервера, особенно при наличии параллельно работающих соединений интенсивно обращающихся к диску. Поэтому сервер Yaffil открывает временные файлы сортировки с флагом FHJE_ATTRIBUTE_TEMPORARY, что предотвращает сброс кэш-буферов на диск операционной системой при наличии достаточного объема кэш-памяти.
При наличии большого количества оперативной памяти для сервера Windows NT, на котором выполняется Yaffil, имеет смысл увеличить приоритет файлового кэша на использование памяти. При этом менеджер памяти будет стараться использовать свободную физическую память как файловый кэш вместо предоставления ее работающим приложениям. За данный параметр настройки отвечает значение LargeSystemCache ключа системного реестра
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerMemory Management.
Для сервера InterBase рекомендуется выставить это значение в 1. Для того чтобы изменение вступило в силу, необходимо перезагрузить систему.
Обратите внимание, что некоторые серверные приложения, такие, как Microsoft SQL Server, могут переустанавливать это значение в 0 при своей инсталляции, поскольку не используют файловый кэш.
Оптимальная структура хранения записей
InterBase использует эффективный способ хранения записей на страницах базы данных, используя алгоритм RLE (run length encoding - кодирование последовательностей) при размещении данных, за счет которого базы данных InterBase являются компактными. Несмотря на то что алгоритм является очень простым, он тем не менее требует вычислительных ресурсов при записи и чтении данных на странице.
В зависимости от характера данных упаковка может оказаться нецелесообразной. Наибольший эффект достигается при сжатии "хвостов" из пробелов длинных текстовых строк (типы данных CHAR и VARCHAR), в то время как короткие нетекстовые данные практически несжимаемы.
Для управления сжатием в Yaffil введен параметр конфигурации SQZ_BLOCK. Этот параметр определяет минимальный размер блока строки таблицы (в байтах), начиная с которого будет производиться сжатие. Блоки строки таблиц менее указанного размера хранятся в исходном виде. С увеличением параметра объем базы данных возрастает за счет сокращения затрат времени процессора на упаковку. В то же время увеличение количества данных больше нагружает дисковую подсистему. В зависимости от характера данных (главным образом количества текстовых полей в таблицах) и определенных параметров процессора и дисков системы существует некоторое оптимальное значение SQZ_BLOCK, обеспечивающее максимальную производительность. Алгоритм упаковки, реализованный в Yaffil, дополнительно выравнивает начало и размер сжатого блока на границу машинного слова.