Вход/Регистрация
Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
вернуться

Борри Хелен

Шрифт:

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

CommitRetaining.

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

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

Тема оптимизации: использование внутренних возможностей

Firebird наследует недокументированную возможность, которая может ускорить выполнение запроса при некоторых условиях. Это RDB$DB_KEY (обычно называется просто db key), внутренний ключ, поддерживаемый сервером базы данных для внутреннего использования при оптимизации запросов и управлении версиями записей. Внутри контекста транзакции, где он используется, он представляет позицию строки в таблице8 [118] .

118

Клавдио Валдеррама (Claudio Valderrama) провел исследования по RDB$DB_KEY, именно его примеры здесь используются. Он живет в Чили, его псевдоним "robocop". Клавдио является официальным инспектором кода в проекте Firebird. Он поддерживает обширный сборник статей и кодов для Firebird и InterBase на своем сайте: http://www.cvalde.net.

Относительно RDB$DB_KEY

Первый урок заключается в том, что RDB$DB_KEY является прямым указателем, связанным с базой данных, а не с физическим адресом на диске. Второй - значения RDB$DB_KEY не следуют в предсказуемой последовательности. Не используйте вычисления, включающие их относительные позиции! Третий урок в том, что они изменчивы - они изменяются после резервного копирования и последующего восстановления, а иногда и после подтверждения транзакции. Главным является понимание мимолетности db key и отсутствие предположений о его существовании в то время, когда ссылающаяся на него операция завершается или отменяется.

Размер RDB$DB_KEY

Для таблиц RDB$DB_KEY использует 8 байт. Для просмотров он использует коэффициент умножения этих 8 байт, сколько таблиц используется в просмотре. Например, если просмотр соединяет три таблицы, его RDB$DB_KEY использует 24 байт. Это важно, когда вы работаете с хранимыми процедурами и собираетесь сохранять RDB$DB_KEY В переменных. Вы должны использовать тип данных CHAR(n) корректной длины.

По умолчанию db key возвращается в виде шестнадцатеричного числа - две шестнадцатеричные цифры представляют каждый байт: 16 шестнадцатеричных цифр возвращаются для 8 байт. Сделайте для одной из ваших таблиц в isql следующее:

SQL> SELECT RDB$DB_KEY FROM MYTABLE;

RDB$DB KEY

000000B600000002

000000B600000004

000000B600000006

000000B600000008

000000B60000000A

Преимущества

Поскольку RDB$DB KEY напрямую указывает на место хранения записи, он будет быстрее для поиска, чем первичный ключ. Если по каким-то причинам в таблице нет первичного ключа или активного уникального индекса, или уникальный индекс допускает пустые значения, то возможно существование полных дубликатов строк. В этих условиях RDB$DB_KEY является единственным способом точной идентификации каждой строки.

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

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

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

Проблемы с производительностью, скорее всего, возникнут, если вы попытаетесь запустить изменения DSQL, похожие на следующий пример, для большой таблицы:

UPDATE TABLEA А

SET A.TOTAL = (SELECT SUM (B.VALUEFIELD)

FROM TABLEB В

WHERE B.FK = A.PK)

WHERE <условия...>

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

CREATE PROCEDURE ...

. .

AS

BEGIN

FOR SELECT B.FK, SUM(B.VALUEFIELD) FROM TABLEB В

GROUP BY B.FK

INTO :B_FK, : TOTAL DO

UPDATE TABLEA A SET A.TOTAL = :TOTAL

WHERE A.PK = :B_FK

AND ...

END

Хотя это и быстрее, тем не менее остается проблема, что записи в А выбираются по первичному ключу каждый раз, когда выполняется проход по циклу FOR ... DO.

Некоторые люди получают лучший результат при этом необычном синтаксисе:

  • Читать дальше
  • 1
  • ...
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: