Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БД_1 / Лекции / Лекция 16 оптимизация.doc
Скачиваний:
46
Добавлен:
11.06.2015
Размер:
709.12 Кб
Скачать

83

Хvi оптимизация работы с базами данных

Проблемы работы с БД

Оптимизация производительности БД

Оптимизация кода запросов

Оптимизация работы СУБД

Оптимизация структур данных

Мониторинг работы БД

Инструменты для оптимизации работы с БД

Проблемы работы с БД

Наиболее серьезными проблемами работы с БД являются:

  • неэффективное использование доступной емкости памяти (до 70% емкости систем хранения тратится впустую);

  • неуправляемое дублирование данных на уровне таблиц, БД и массивов данных;

  • неэффективные приложения, захватывающие оперативную память;

  • увеличение объемов входных потоков данных, требующие быстрой переработки их в оперативной памяти;

  • рост числа оборудования (серверов);

  • отсутствие формализации и плохое документирование выполняемых операций;

  • необходимость хранения всех типов данных (сообщений электронной почты, электронных таблиц, текстовых документов, фотографий, аудиозаписей, кинофильмов и даже журналов регистрации мгновенных сообщений) и организации их поиска;

  • отсутствие проработанной стратегии архивирования данных на дешевых жестких дисках и магнитных лентах;

  • недостаточное развитие передовых методов управления метаданными и нормативно-справочной информацией.

Ниже перечислены вопросы, ответы на которые позволяют определить критерии оптимизации работы с БД:

  • Сколько одновременно активных пользователей должна поддерживать система?

  • Основные или доминирующие типы запросов к системе?

  • Какова стратегия индексации данных?

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

  • Насколько велик чистый размер БД?

  • Имеется ли достаточное количество дисковых накопителей и адаптеров, сконфигурированных для обеспечения обработки данных?

  • Имеется ли достаточная емкость дисковой памяти для хранения необработанных данных, индексов, временных табличных пространств, а также место для возможного увеличения объема данных?

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

  • Требуется ли специальная выделенная сеть для организации связи между клиентскими системами и сервером?

  • Согласована ли предполагаемая стратегия резервного копирования с типом, числом и местом размещения устройств резервного копирования?

Критериями оптимизации работы БД являются:

  • восстановление данных - не более 10 минут;

  • скорость доступа к данным - не более 5 с.;

  • простота обслуживания – 1 администратор на 1 Тбайт данных.

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

Таблица 1 - Методы повышения эффективности работы БД

Метод

Отражается на

улучшении пропускной способности

увеличении скорости приложений

Кэширование файлов

X

X

Оптимизация глобальной сети

X

-

Кэширование Web

X

X

Сжатие файлов

X

-

Блочное тиражирование

X

-

Динамическое кэширование

X

X

Ускорение SSL

-

X

Таким образом, при работе с БД необходимо оптимизировать работу с БД с учетом жизненного цикла данных:

  • оптимизация производительности БД (использованием дискового пространства, процессами резервного копирования и восстановления);

  • оптимизация кода запросов (уменьшение времени поиска данных и доступа к данным);

  • оптимизация работы СУБД;

  • оптимизация структур данных, включая создание и использование унифицированных моделей данных;

  • автоматизация мониторинга работы БД.

Оптимизация производительности БД

Производительность СУБД оценивается:

  • временем выполнения запросов;

  • скоростью поиска информации в неиндексированных полях;

  • временем выполнения операций импортирования БД из других форматов;

  • скоростью создания индексов и выполнения таких массовых операций, как обновление, вставка, удаление данных;

  • максимальным числом параллельных обращений к данным в многопользовательском режиме;

  • временем генерации отчетов.

На производительность СУБД оказывают влияние следующие факторы [7,8]:

  • средства соблюдения целостности данных, которые создают дополнительную нагрузку;

  • ошибки проектирования и построения БД (большое количество связанных таблиц, отсутствие индексирования, др.);

  • надежность работы БД;

  • индексирование таблиц.

Целостностность данных обеспечивается средствами, позволяющими сохранить корректность и полноту БД. К средствам обеспечения целостности данных на уровне СУБД относятся [5]:

  • встроенные средства для назначения первичного ключа, в том числе средства для работы с типом полей с автоматическим приращением новых уникальных значений, уникальные идентификаторы записей должны задаваться СУБД только в том случае, когда недоступен определенный пользователем первичный ключ;

  • средства поддержания ссылочной целостности, которые обеспечивают запись информации о связях таблиц и автоматически пресекают любую операцию, приводящую к нарушению ссылочной целостности.

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

  • плохой проект/планирование - если не сделать правильный проект БД в самом начале, то потом любые изменения в структуре БД будут оказывать воздействие на эксплуатацию БД;

  • слабые стандарты именования - имена таблиц, атрибутов, связей, ограничений значений по умолчанию должны позволить программистам и пользователям быстро и легко понять, к какой таблице относятся те или иные атрибуты и какие данные она содержит.

Чтобы обеспечить безотказную работу на этапе проектирования БД, необходимо определить:

  • график доступности БД для пользователей;

  • периоды профилактического простоя БД;

  • периоды ограничений доступа к БД;

  • альтернативные источники данных после отказа БД;

  • объем повторно вводимой информации после сбоев;

  • допустимое время восстановления БД после сбоя;

  • график регулярных суточных заданий;

  • список приложений, работающих на серверах;

  • резервирование на случай отказа основных аппаратных средств;

  • запас мощности сервера, на котором функционирует БД;

  • скорость передачи данных при резервном копировании;

  • носители для хранения резервных копий;

  • места для хранения резервных носителей (рядом с основным сервером, в другом помещении и удаленном сервере).

При анализе задач регулярной загрузки данных и получения отчетов проектировщик БД должен выделить:

  • периодичность обмена данными и объем передаваемых данных;

  • степень синхронизации двух систем;

  • методы транспортировки данных;

  • форматы данных для обмена;

  • порядок выполнения операций;

  • мероприятия, которые необходимо выполнить при сбое, во время регулярной загрузки данных и получения отчетов;

  • правила определения ошибочных записей (при загрузке);

  • правила регистрации операций передачи и приема данных;

  • графики сбора и передачи данных пользователям;

  • график разработки и тестирования собственных утилит или скриптов обмена данными;

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

В большинстве случаев причиной плохой производительности системы является приложение, в котором либо не оптимизированы SQL-запросы, либо в БД не используются индексы. Желательно создать спецификацию идентификации таблиц и индексов в БД. Это поможет избежать многих проблем, а также создаст условия полноценного использования индексов.

Индексирование - один из наиболее эффективных способов наращивания производительности БД, входит в число основных механизмов БД. Как правило, строки БД хранятся в том порядке, в каком создаются. Для извлечения из записи БД некоторой произвольной величины требуется последовательное сканирование соответствующих строк БД. Индекс создает отдельное множество строк, упорядоченных в соответствии с выбранным индексом и содержащих указатели на исходные строки. Индексированные таблицы просматриваются значительно быстрее, чем неиндексированные таблицы. Однако индексирование "съедает" дополнительное дисковое пространство. Кроме того, на модификацию индексированной таблицы требуется больше времени, поскольку все применяемые индексы тоже приходится корректировать. СУБД проводят индексацию автоматически; в крупных СУБД - индексация автоматическая или выборочная.

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

В зависимости от того индексируется или нет таблица, выполнение оператора select, который запрашивает одну определенную запись, может приводить к тому, что СУБД будет читать из таблицы всего одну запись, либо каждую запись в таблице большого объема данных. Часто, для того чтобы оптимально обрабатывать несколько различных шаблонных обращений, генерируемых приложением, таблица должна индексироваться более чем одним ключом или набором ключей. Хорошо осмысленная индексация может иметь весьма существенное воздействие на общую производительность системы.

Во многих СУБД первичный ключ индексируется автоматически. Для внешнего ключа это не всегда так. Чтобы обеспечить наилучшую работу объединений, обязательно проиндексируйте каждый внешний ключ в БД. Следующий кандидат на индексацию - это любой столбец, который будет использоваться для сортировки, т.е. столбец, который будет постоянно использоваться в выражении "order by". Также стоит проиндексировать столбцы, которые будут использоваться для ограничения возвращаемого набора данных. Это, например, те столбцы, которые постоянно фигурируют в выражениях "where".

В СУБД Oracle введена технология секционирования (partitioning), которая позволяет загружать большие таблицы и индексы по частям, а не как единое целое, и дает существенный выигрыш в производительности СУБД. Причина выигрыша заключается в том, что при выполнении запроса к БД исключается из области поиска разделы, которые не содержат данных, относящихся к запросу. Наряду с ранговым секционированием в СУБД Oracle представлены два других механизма секционирования – композитное и хэш-секционирование. Хэш-секционирование предоставляет простой способ разделения данных на контейнеры одинакового размера, которые распределяются по разным устройствам ввода/вывода и даже по разным машинам. Производительность запроса в этом случае повышается за счет распределения операций ввода/вывода по разным устройствам. При этом улучшается производительность как обычных, так и параллельных запросов. Композитное секционирование объединяет преимущества рангового и хэш-секционирования – первоначально данные секционируются по рангу значения, а затем администратор определяет количество хэш-подразделов. При этом гарантируется полная поддержка локальных индексов и синтаксиса SQL, как при работе с обычными (несекционированными) таблицами.

Соотношение запрос/индекс/диск. Любая транзакция, которая находит небольшое число специально поименованных записей из таблицы "по индексному ключу" будет представлять собой операцию произвольного доступа к диску. Любое обновление БД связано и с обновлением всех затронутых индексов, а также с выполнением записи в журнал. В правильно спроектированной БД каждая таблица должна содержать первичный ключ, что означает наличие индекса. Если используется составной индекс, то поиск по всем атрибутам, входящим в индекс, начиная со второго, будет медленным. Эту особенность следует учитывать при определении индексов в схеме БД, а именно:

  • индексировать нужно атрибуты, по которым наиболее часто осуществляется поиск или соединение (наличие индекса замедляет операции модификации, но ускоряет поиск);

  • наличие индекса обязательно, если для атрибута или набора атрибутов указано ограничение unique, то такие индексы создаются СУБД автоматически;

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

  • атрибуты, входящие во внешний ключ, также следует индексировать, если СУБД не делает эту операцию автоматически при декларации внешнего ключа;

  • в некоторых СУБД поддерживаются хеш-индексы, например, для кластеров, такие индексы эффективно используются при поиске на равенство;

  • создавайте индексы, которые позволят осуществлять быстрый поиск данных внутри таблиц для столбцов, у которых часто используются предложения WHERE, ORDER BY и GROUP BY;

  • создавайте кластерные индексы вместо некластеризованных для того, чтобы увеличить производительность запросов, которые возвращают диапазон значений и для запросов, которые содержат предложение GROUP BY или ORDER BY в пунктах, которые возвращают результаты сортировки;

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

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

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

  • удаляйте индексы, которые не используются (создавайте новые индексы только после анализа данных об их использовании, видов и масштабов запросов).

Кластеризация — это попытка разместить рядом в одном физическом блоке данные тех строк, доступ к которым осуществляется при помощи одинаковых значений ключа. Индексные кластеры, например, удобно использовать для хранения родительской и дочерних строк таблиц, связанных ссылочной целостностью. Кластеры удобно определять для тех наборов атрибутов, соединение по которым проводится наиболее часто, поскольку это увеличивает скорость поиска. Следует отметить, что в реализациях СУБД используется, как правило, один кластер.

В таблице записей, содержащих информацию о персонале, можно использовать в качестве ключей символьные поля last_name и first_name. Лучше использовать числовое ключевое поле, например, person_id. Если данные не содержат такого поля, то необходимо создать автоинкрементное поле, которое не будет содержать никаких реальных данных и будет, лишь играть роль ключевого поля. Числовые поля имеют множество преимуществ. Вероятность ошибочного использования числа гораздо меньше вероятности ошибочного использования имени. При изменении имени человека (например, ввиду вступления в брак) не потребуется изменять в своем коде все ссылки на него. Кроме того, объединение записей, имеющих числовое ключевое поле, выполняется гораздо эффективнее, чем объединение записей с текстовым ключевым полем. Следует взять за практику создавать числовое поле первичного ключа при формировании каждой новой таблицы.

Использование столбцов identity/guid в качестве единственного ключа. Первая нормальная форма диктует, что все строки в таблице должны однозначно идентифицироваться первичным ключом. SQL Server, например, позволяет определить числовой столбец как столбец IDENTITY, после чего автоматически генерируются уникальные значения для каждой добавляемой строки. Кроме того, можно использовать NEWID() (или NEWSEQUENTIALID()) для генерации случайного 16-байтового уникального значения для каждой строки. Такие типы значений, когда они используется как ключи, называются суррогатными ключами.

Проблема состоит в том, что слишком часто проектировщики используют столбец суррогатного ключа в качестве единственного ключевого столбца в таблице. Значения суррогатного ключа не представляют никакого фактического значения в реальном мире; они предназначены исключительно для того, чтобы однозначно идентифицировать каждую строку. В любой таблице должен быть некоторый ключ, чтобы гарантировать уникальность строк.

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

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

Для выявления самых медленных SQL запросов нужна следующая информация:

  • Кэширование (это описывается на уровне выполнения запроса);

  • Какие индексы были использованы?

  • Сколько операций ввода / вывода произошло (как физических, так и логических);

  • Сколько времени было потрачено на выполнение запросов;

  • Сколько времени тратится на ожидание ресурсов;

  • Какие ресурсы запрос ждал.

Советы, которые можно использовать, чтобы получить максимальную отдачу от СУБД [13]:

- используйте каждый сервер отдельно для СУБД, веб-сервера, сервера приложений, ГИС-сервера;

- применяйте несколько дисковых контроллеров, чтобы избежать узкого места ввода / вывода;

- купите соответствующую конфигурацию RAID дисков (RAID 5 дешевле, чем RAID 0 +1 и RAID 5 работает лучше для операций чтения, чем для операции записи, а RAID 0 +1 работает лучше для записи интенсивных операций), по возможности следует выбирать RAID диск, реализованный на аппаратном, а не программном уровне;

- обеспечьте отдельный диск для часто используемых таблиц и индексов;

- уточните нагрузки и метрики контроля за работой СУБД, постоянно отслеживайте показатели работы системы;

- организуйте отдельные БД для OLAP и OLTP нагрузок (рабочие нагрузки на одном сервере должны быть разработаны так, чтобы они не мешали друг другу - OLAP для долго выполняющихся запросов, OLTP нагрузки характеризуется множеством мелких, но быстрых операций);

- используйте зафиксированный размер БД, выделенный при ее создании, тогда можно быть уверенным, что выделенное пространство будет непрерывным (если установить опцию «автоматическое увеличение дискового пространства», то оно будет выделено только в случае необходимости и тогда БД будет фрагментирована);

- БД временного хранения храните на отдельном диске, которые используются при выполнении таких операций, как GROUP BY или ORDER BY;

- данные и журналы должны находиться на разных физических дисках, что позволяет выполнять операции с максимальной производительностью;

- используйте секционирование таблиц, что позволяет хранить таблицу на разных физических дисках;

- получайте только необходимые данные (для того чтобы уменьшить размер передаваемых данных необходимо в select вместо (*) указать только столбцы, которые нужны);

- используйте параметры в запросах, что позволит не проводить повторную оптимизацию запросов;

- используйте в приложениях тип данных, который работает для каждого столбца (явные и неявные преобразования могут быть дорогостоящим с точки зрения времени, которое требуется для выполнения преобразований);

- используйте тип поля VARCHAR вместо «текст» для столбцов, которые содержат менее 8000 символов (тип текстовые данные хранятся отдельно от текста);

- используйте тип данных Unicode (NCHAR и NVARCHAR) только в случае необходимости, т.к. этот тип использует в два раза больше места для хранения по сравнению с ASCII данными;

- не изменяйте модель данных после того как система уже находится в эксплуатации;

- избегайте длительных операций в триггерах (они всегда являются частью INSERT, UPDATE или DELETE операций, длительные операции могут вызвать блокировку других запросов);

- избегайте дорогих операторов, таких как объединение, LIKE ("% значение %"), которые требуют ресурсоемких операций;

- используйте системные хранимые процедуры sp_executesql для динамического кода в приложении;

- получайте статистику выполнения запросов.

Для современных многоядерных серверов необходимо распараллеливать выполнение запроса по ядрам за счет использовани хинта /*parallel ...*/. Это позволит сократить время обработки данных в семь раз.

Оптимизация кода запросов

Ресурсоемкие операции это запросы, содержащие операторы DISTINCT, UNION, MINUS, INTERSECT, ORDER BY или GROUP BY, которые заставляют СУБД выполнять операцию сортировки. Оператор DISTINCT требует выполнить одну операцию сортировки, другие операторы заставляют ядро выполнить как минимум две операции сортировки. Всегда следует искать другие пути выполнения подобных запросов. Большинство запросов, содержащих UNION, MINUS и INTERSECT, могут быть выполнены иными способами. Не делайте ненужных объединений (joins).

Первым шагом в оптимизации запроса должно быть исключение полного сканирования таблицы. Для первоначальной оптимизации запросов рекомендуется использовать команду EXPLAIN PLAN. Использование индексов в запросах оправдано, если запрос извлекает меньше 15% строк из таблицы. Во всех остальных случаях полный просмотр таблицы (Full Table Scan FTS) будет работать быстрее.

Одна из наиболее медленных команд в SQL это команда UPDATE. Это является следствием того, что большинство согласованных изменений в таблицах требуют полного просмотра таблиц. В результате этого эти операции являются ресурсоемкими и очень медленными, когда таблицы слишком большие.

Чтобы добиться максимального повышения производительности БД, можно использовать несколько разных стратегий оптимизации программного кода.

Извлечение из БД длинного списка записей для отображения на одной непрерывной web-странице является нерациональным. Следует взять за один раз только часть записей (10, или 50, или 100), а затем, чтобы отобразить следующую группу записей, использовать кнопку "Страница 1,2,3, ..". Ключевое слово limit ограничивает число возвращаемых записей. Ключевое слово offset (смещение) пропускает определенное число записей, возвращая следующие за ними записи. Чтобы получить третью группу пользовательских записей в количестве 50 штук, следует использовать запрос следующего вида:

select customer_id, customer_name from customer order by customer_id limit 50 offset 100.

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

Оператор Case языка SQL может делать выбор на основе значения входного параметра. В таком случае результат оператора Select можно контролировать, используя оператор Case, как это сделано в следующем примере:

select product_name,

case

when price < 5 then 'cheap'

when price > 5 and price < 20 then 'ok'

else 'too expensive for my taste'

end as product_price from products order by product_name;

В результате будем иметь набор записей, состоящий из двух столбцов: первый столбец содержит наименование продукта, второй - избранный интервал цены.

Бывают случаи, когда набор параметров отбора данных определяется только перед самим отбором - а изначально, во время проектирования программы, не известен. Например, надо выбрать клиентов, "засветившихся" в БД торговой фирмы за определенный срок; или сделавших покупки на сумму больше некоторой заданной. Или приходится искать конкретного человека, используя частично известные анкетные данные. Ситуация усложняется еще больше, если для определения, какие записи нужно выбрать, а какие нет, надо вызывать какую-нибудь функцию, реализующую сложные и ресурсоемкие вычисления. Динамический SQL позволяет строить текст запроса непосредственно внутри кода PLSQL и затем выполнять его.

Существует три метода, с помощью которых СУБД может найти строку в таблице [http://www.interface.ru/home.asp?artId=9890]:

  • просмотр всех строк в таблице по порядку и проверка каждой строки на соответствие конкретному условию, этот метод называется полное сканирование таблицы (full table scan, FTS), он является самым медленным и наименее эффективным;

  • использование индекса для поиска строки;

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

Скорость выполнения запросов содержащих предложения GROUP BY может быть значительно повышена путем исключения лишних строк из операции группировки. Наиболее выгодно первым в WHERE помещать предикат, связанный с тем условием, которое возвратит наибольшее количество строк, а последним – предикат, возвращающий наименьшее количество строк. Тем самым мы минимизируем количество проверок на '!=' во втором SELECT.

Самым быстрым способом повышения производительности является замена встроенных в него операторов SQL на хранимые процедуры. Хранимые процедуры - это набор SQL команд. Такие процедуры предварительно компилируются, что существенно повышает производительность БД. Если процедуры достаточно универсальны, то можно использовать их в других задачах.

Выполнение SQL-кода в таких средах, как PHP, ASP и JSP, а также в средах некоторых других языков разработки в виде хранимых процедур позволяют заметно снизить интенсивность сетевого трафика. Если возникнет необходимость в масштабировании приложения, гораздо проще расширить его код на несколько прикладных серверов, когда большая часть логики доступа к БД хранится и выполняется в рамках самой БД.

Хранимые процедуры делают разработку БД намного более прозрачной. Хранимые процедуры позволяют "инкапсулировать" любые структурные изменения, которые потребуется сделать в БД, чтобы влияние на пользовательские интерфейсы было минимально. Используйте хранимые процедуры для обеспечения доступа к данным как метод для изоляции слоя БД от пользователей.

Хранимые процедуры могут обеспечить специфичный и гранулированный доступ к системе. Например, можно иметь несколько хранимых процедур, которые определенным образом обновляют таблицу X. Если пользователю необходимо обновить конкретный столбец в таблице, и нужно гарантировать, что он никогда не обновит никакие другие столбцы, то можно просто предоставить этому пользователю разрешение на выполнение только этой одной процедуры, которая позволит ему выполнить необходимое обновление.

Если новичок пишет неоптимальный код (подобно использованию курсора для построчной обработки таблицы, содержащей десять миллионов строк, чтобы найти одно значение вместо использования предложения WHERE), процедура может быть переписана. Хранимые процедуры облегчают повторное использование кода и дают прирост производительности. В случае, когда необходимо ускорить непосредственно передаваемый код SQL, он может быть закодирован в хранимой процедуре без искажения.

Есть установка СУБД "Вынужденная параметризация" (PARAMETERIZATION FORCED), которая при включении заставит сохранять коды всех запросов.

Ниже даны правила создания быстро выполняющихся запросов:

  • не следует выключать использование индексов посредством модификации поля в предложении where;

  • в предложении from последней следует помещать таблицу, из которой извлекается наименьшее количество строк;

  • следует использовать оператор exists там, где это возможно;

  • не следует заставлять СУБД часто выполнять компиляцию запросов, следует отдавать предпочтение конструкции bind;

  • необходимо знать объем данных, значения полей и использовать в тестах реальные наборы данных;

  • при написании запросов следует давать синонимы таблицам;

  • не применяйте оператор!= если можно обойтись без него используйте средства для наблюдения за ходом выполнения запросов, например, oracle trace facility.

Оптимизация работы СУБД

Для оптимизации работы СУБД существует несколько способов, это:

  • блокировка доступа к данным при наличии конфликтующих одновременных обращений;

  • использование серверов приложений;

  • эффективное использование оперативной памяти и памяти на дисках;

  • правильный выбор размера буфера ввода/вывода;

  • кэширование данных;

  • повышение эффективности работы сети;

  • работа с объектными файлами.

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

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

Оперативная память. Среди различных компонентов аппаратуры сервера БД конфигурация памяти системы обычно имеет самое большое воздействие на ее производительность. Большая часть оперативной памяти используется СУБД в качестве буфера (кэша) данных, позволяющего во многих случаях устранить необходимость выполнения физического ввода/вывода с диска. Поскольку обращение к основной памяти выполняется примерно в 30000 раз быстрее, чем обращение к быстрому диску, минимизация ввода-вывода данных с диска является первостепенной задачей. Обращение к памяти выполняется примерно за 500 мс даже в самых худших условиях. Настройка конфигурационных параметров бесполезна, если в системе не хватает основной памяти. Лучше закупить избыточный объем памяти, чем недооценить его.

В новых версиях СУБД данные хранятся не на диске, а в оперативной памяти, что многократно увеличивает быстродействие. Хранимые процедуры, применяемые к потоку данных, также увеличивают производительность обработки данных. Миграции БД в оперативную память способствует использование 64-разрядных архитектур, где преодолено ограничение в 2 Гб непосредственно адресуемой памяти.

Использование дисковой памяти. Следует зарезервировать 5-10% памяти для хранения индексов, хранимых процедур и другой управляющей информации СУБД. Обычно предусмотриваю примерно удвоенный объем дискового пространства по сравнению с объемом "чистых" данных. Это обеспечивает некоторую гибкость для создания индексов и в итоге позволяет улучшить производительность приложения. Объем памяти для индексации и других служебных функций по отношению к «чистым данным» должен составлять примерно 0.75. Например, при использовании устанавливаемых по умолчанию параметров памяти СУБД Oracle, объем "чистых" данных увеличивается на 30% при хранении их в БД даже без индексации.

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

Другим фактором, влияющим на конфигурацию подсистемы ввода/вывода, является предполагаемое распределение данных по дискам. Хотя технически возможно объединить по несколько логических функций на одних и тех же (физических или логических) дисках, для подсистемы ввода/вывода это оказывается очень разрушительным и приводит к неудовлетворительной производительности. Поэтому даже небольшая по объему БД должна иметь четыре диска (для ОС, области подкачки (swap) данных, журнала и индексов). Конфликты по этим ресурсам на сервере БД с ограничениями ввода/вывода являются самой большой проблемой обеспечения производительности сервера БД, для которого БД была настроена. Крупные БД должны учитывать зеркалирование дисков и перекрытие ресурсов. Наиболее продуктивным и достаточно эффективным по стоимости способом распределения данных является обеспечение всех основных логических сущностей отдельным диском.

Если хранить БД объемом около 2 Гбайт (1.5 Гбайта чистых данных) на одном диске, то при выполнении приложением практически любого обновления БД, каретка диска все время будет сновать челноком по диску для каждой транзакции. В частности, процесс формирования журнала, который должен писаться синхронно и медленно, в действительности будет выполняться в режиме произвольного доступа, а не в режиме последовательного доступа к диску. Это будет существенно задерживать каждую транзакцию обновления БД.

Выбор размера буфера ввода/вывода. Обычно буфер СУБД Oracle (Глобальная Область памяти - System Global Area- SGA), в Sybase (Кэш Разделяемых Данных - Shared Data Cashe). реализуется как большой массив разделяемой памяти, и его размер определяется специальным параметром в управляющем файле или таблицах БД. Размер памяти, необходимый для организации кэш СУБД на диске, меняется в широких пределах от приложения к приложению, но для примерной оценки размера буфера могут быть использованы эмпирические правила. В зависимости от размера БД размер области памяти под буфера может варьироваться в очень широких пределах. Обычно обеспечивается кэш объемом в 1% всех данных даже для очень больших БД, например, 500 Мбайт основной памяти позволяют обслужить БД объемом 50 Гбайт. Очень грубо размер кэш данных можно оценить, выделяя от 50 до 300 Кбайт на каждого пользователя. Большинство СУБД имеет механизм сообщений об эффективности использования кэш разделяемых данных и могут обеспечивать оценку того, какой эффект будет давать увеличение или уменьшение размера кэш.

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

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

Отдельные логические функции СУБД следует реализовывать на отдельных выделенных дисковых ресурсах; необходимо планировать размещение данных на дисках для минимизации количества и длительности позиционирования головок.

При разработке подсистемы ввода/вывода должно быть уделено внимание не только максимальной емкости ее компонентов, но также уровню использования (загруженности) каждого ресурса. Большинство параметров, используемых для описания емкости ресурсов, так или иначе, связаны с пропускной способностью.

Экспериментальные результаты показывают, что если должна поддерживаться пиковая производительность, то степень загруженности шины должна поддерживаться на уровне 40%. Аналогичным образом, степень загрузки дисков должна поддерживаться на уровне 60%. Диски могут выдерживать значительно степень загрузки, чем шина, поскольку во встроенных дисковых контроллерах имеется интеллект и средства буферизации.

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

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

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

После начальной инсталляции необходимо наблюдать за работой СУБД и перемещать данные до тех пор, пока каждый дисковый накопитель не будет загружен менее чем на 60%. Особое внимание следует уделять влиянию резервного копирования в режиме on-line на работу системы.

По определению семантики оператора SQL COMMIT_WORK любая СУБД должна гарантировать, что все обновления БД должны направляться и фиксироваться в памяти, которая обеспечивает устойчивое хранение данных даже в условиях сбоев системы или отказов питания. Чтобы СУБД могла дать такую гарантию, она должна выдавать для выполнения, по крайней мере, некоторые из своих операций записи синхронно. Во время выполнения таких записей ОС блокируется и не возвращает управление вызвавшей программе до тех пор, пока данные не будут зафиксированы в стабильной памяти. Хотя эта стратегия очень надежна, вместе с тем она приводит к существенному замедлению операций, поскольку при выполнении синхронных записей обязательно требуется, чтобы данные были записаны непосредственно на дорожку диска. Синхронная запись на "чистый" диск занимает примерно 20 мс, а синхронная запись в файловую систему может занять в несколько раз больше времени.

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

Доступ к данным в общем случае подчиняется правилу - 80% всех обращений выполняются к 20% данных. Самым простым и наиболее полезным является эмпирическое правило, которое называется "правилом пяти минут". Это означает, что данные, к которым обращения происходят более чем один раз в пять минут, должны кэшироваться в памяти. Соответственно, чтобы оценить размер кэш данных необходимо просуммировать объемы всех данных, которые приложение предполагает использовать более часто, чем один раз в пять минут на уровне всей системы.

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

Необходимо наблюдать за загрузкой сети. Даже если с пропускной способностью сети не возникает никаких вопросов, проблемы задержки часто приводят к тому, что более удобной и полезной оказывается установка отдельной, выделенной сети между фронтальной системой и сервером БД.

Уже на этапе проектирования БД необходимо определить наиболее эффективные методы и средства хранения объектных файлов (статические изображения, звуковые файлы, фильмы, видеоматериалы, текстовые документы, которые становятся частью БД и их можно хранить в поле типа blob - binary large object). Поля blob можно хранить либо в БД, либо в файловой системе. Универсальные решения для организации поиска основаны на создании каталога документов. В этом случае пути к объектам blob хранятся в БД. Хранение объектов blob в файловой системе потребует чуть больше работы, зато позволит добиться гораздо более высокой производительности (скорости поиска и доступа к данным), чем при хранении их в БД. С увеличением числа сохраняемых двоичных объектов в БД производительность быстро уменьшается. Кроме того, удаление таких объектов может привести к образованию в файлах БД большого числа "мертвых зон". Хранение объектов blob в файловой системе, напротив, облегчает создание ссылок на загружаемые из web-страниц объекты. После загрузки информации web-сервер обслуживает обращение к файлу, а процессор БД занимается в это время другими задачами. Дополнительным преимуществом также является и то, что администратор может легко каталогизировать и администрировать мультимедийные файлы, записанные на диск, а также делать их резервные копии.

Чтобы решить, стоит ли видеоматериал заказывать, или чтобы отыскать в нем минутный фрагмент по интересующей теме, нужны соответствующие методы поиска и доступа, и здесь возможны самые разные подходы - это могут быть наборы ключевых кадров, текстовые индексы, средства поиска сегментов, обладающих заданными характеристиками. Объем спутниковых изображений велик, передача множества снимков, среди которых пользователь будет искать нужные ему, требует слишком много времени. Здесь также поможет поиск по каталогу, получение галереи изображений (уменьшенных копий изображений), из которых пользователь делает выборку отдельных снимков.

Файловая система потребляет примерно 10% от форматированной емкости дисков для метаданных о файлах. Более того, файловая система резервирует 10% оставшегося пространства, чтобы обеспечить быстрый поиск свободного пространства в случае расширения файлов (этот дополнительный объем памяти в принципе может быть использован, но за счет потенциально значимых дополнительных задержек, которые возникнут при открывании или расширении файлов). Если СУБД работает с данными через файловую систему, то по сравнению с БД емкость дисковой памяти в целом уменьшается на 19% [9, 10, 11]. Стандартные утилиты UFSDUMP и UFSRESTORE OC UNIX могут использоваться для того, чтобы производить надежное резервное копирование и восстановление СУБД. Для этого могут также использоваться инструментальные средства резервного копирования и восстановления от поставщиков СУБД. Можно также использовать средства копирования физических томов. Хранение данных в файловой системе позволяет выполнять единообразные, надежные процедуры для того, чтобы работать через систему и сеть.

Поскольку дисковое пространство для таблиц часто заранее распределено в файловой системе обычно удается агрегировать данные в блоки объемом по 56 Кбайт, в то время как менеджеры памяти СУБД обычно оперируют только страницами размером в два (иногда восемь) Кбайт. Последовательное сканирование таблиц или индексов, хранящихся таким образом, часто может оказаться более эффективным, чем эквивалентных таблиц, хранящихся более традиционным способом. Если в операциях системы доминирует последовательное сканирование (или операции соединения - JOINS, которые часто подразумевают последовательное сканирование), хранение данных в файловой системе обеспечивает более высокую производительность.