8 июн. 2010 г.

Предварительные результаты по внешним ключам

Для тестирования была использована действующая база ВМК размером 29,912,520 Кб. Были конвертированы все внешние целочисленные ключи, удовлетворяющие следующим условиям:
  • В таблице более 10 000 записей.
  • Уникальных значений в ключе не более 200.
  • Ключ не ссылается на эту же таблицу.
Всего ключей, удовлетворяющих условиям, набралось 266. После их удаления и процедуры бэкапа-разбэкапа базы ее размер уменьшился до 23,752,136 Кб или на 21%.

После этого мы проверили скорость выполнения запроса на изменение данных на таблице AC_ENTRY, которая содержит более 9 млн. записей. Текст команды приводится ниже:
update ac_entry set
  companykey = 147048034,
  usr$gs_department = 147048036,
  currkey = 147021255,
  usr$gs_service = 147089059
Четыре изменяемых поля — это сконвертированные ссылки. Проверка целостности осуществляется с помощью триггера следующего вида:
CREATE TRIGGER xxx ON AC_ENTRY
  AFTER UPDATE
  POSITION 32000
BEGIN 
  IF (NEW.USR$GS_SERVICE IS NOT DISTINCT FROM 
    OLD.USR$GS_SERVICE) THEN EXIT;

  IF (NEW.USR$GS_SERVICE IS NOT NULL) THEN 
  BEGIN 
    IF (NOT EXISTS (SELECT id FROM gd_ref_constraint_data 
      WHERE value_data = NEW.USR$GS_SERVICE 
        AND constraintkey = 388626603)) THEN 
    BEGIN
      IF (NOT EXISTS (SELECT ID FROM GD_GOOD 
          WHERE ID = NEW.USR$GS_SERVICE)) THEN
        EXCEPTION gd_e_fkmanager 'message';

      RDB$SET_CONTEXT('USER_TRANSACTION', 
        'REF_CONSTRAINT_UNLOCK', '1');
      INSERT INTO gd_ref_constraint_data 
        (constraintkey, value_data, value_count)
        VALUES 
        (388626603, NEW.USR$GS_SERVICE, 1);
      RDB$SET_CONTEXT('USER_TRANSACTION', 
        'REF_CONSTRAINT_UNLOCK', '0');
    END
  END
END
Время выполнения запроса:
  • На новой базе — 1945 сек.
  • На старой базе — 2642 сек.
Получаем ускорение на 26%. Окончательные выводы можно будет сделать после тестирования на 2-3-х других базах.

1 комментарий:

Александр комментирует...

А можно привести такой эксперимент?
1. Удаляем из ac_entry допустим 1млн записей.
2. Коммит
3. Вставляем в ac_entry 1млн записей.
4. Коммит.

Отправить комментарий