Страница 2 из 3

Добавлено: 22 июн 2006, 09:29
CCB
конечно проверял, ставил точку останова на ExecSQL(ExecQuery), наступал на F8 и доооооооооолго ждал перехода на следующий оператор (обычно Commit), а в это время FireBird начинает загружать камень процентов на 80-90...

Добавлено: 22 июн 2006, 09:32
CyberMax
Не понял, у тебя что, Commit после обновления каждой записи? :shock:

Добавлено: 22 июн 2006, 09:33
CCB
CyberMax писал(а):Не понял, у тебя что, Commit после обновления каждой записи? :shock:
я уже по всякому пробовал - результат один и тот же...

Добавлено: 22 июн 2006, 09:35
CyberMax
Page buffers ставил уже?

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

Добавлено: 22 июн 2006, 09:43
CCB
CyberMax писал(а):Page buffers ставил уже?

Так, давайка кинь скрипт этой таблицы, со всем индексам, триггерами и прочим. Ну и плюс код, который используется в настоящее время.
прям сюда кидать?
кстати, чё-та не найду, как Page buffers выставить...

Добавлено: 22 июн 2006, 09:47
CyberMax
Да, кидай сюда.
Поставь лучше 8192 буферов =)
gfix -buffers 8192 -user SYSDBA -password masterkey database_name.fdb

Добавлено: 22 июн 2006, 10:06
CCB
Установка Page buffers не помогла...

вот так это выглядит:

Код: Выделить всё

CREATE TABLE OBJECTS (
    ID                 INTEGER NOT NULL,
    PARENT_ID    INTEGER DEFAULT 0 NOT NULL,
    TYPE_ID        INTEGER DEFAULT 0 NOT NULL,
    CH_COUNT     INTEGER DEFAULT 0 NOT NULL,
    OBJ_NAME      VARCHAR(255) DEFAULT 'noname' NOT NULL,
    STATUS         SMALLINT DEFAULT 0 NOT NULL,
    TYPE_DEVICE  INTEGER DEFAULT 0 NOT NULL,
    INFO         BLOB SUB_TYPE 2 SEGMENT SIZE 16384
);
------------------------------------------------------------
ALTER TABLE OBJECTS ADD CONSTRAINT PK_OBJECTS PRIMARY KEY (ID);
------------------------------------------------------------
CREATE INDEX OBJECTS_IDX1 ON OBJECTS (PARENT_ID);
------------------------------------------------------------
CREATE PROCEDURE PROC_GEN_OBJECTS_ID 
RETURNS (
    ID INTEGER)
AS
BEGIN
  ID=GEN_ID(GEN_OBJECTS_ID, 1);
  SUSPEND;
END;
------------------------------------------------------------
CREATE TRIGGER INS_OBJ FOR OBJECTS
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  update objects ob set ob.ch_count=ob.ch_count+1
  where ob.id=new.parent_id;
end;
------------------------------------------------------------
CREATE TRIGGER UPD_OBJ FOR OBJECTS
ACTIVE BEFORE UPDATE POSITION 0
AS
begin
  update objects ob set ob.ch_count=ob.ch_count-1
  where ob.id=old.parent_id;
  update objects ob set ob.ch_count=ob.ch_count+1
  where ob.id=new.parent_id;
end;
------------------------------------------------------------
...
type
TRecInfoReg=record
  ID: Integer;
  Info: TInfo;
end;

ArrayIDRegisters: Array of TRecInfoReg;
...
IBQuery1: TIBQuery;
Query2: TIBSQL;
...

IBQuery1.SQL.Clear;
IBQuery1.SQL.Add('select * from proc_get_object('+IntToStr(IDSubSt)+') where typeobj=23');
IBQuery1.Open;

Query2:=TIBSQL.Create(Self);
Query2.Database:=IBDatabase1;
Query2.Transaction:=IBTransaction2;

IBQuery1.FetchAll;

SetLength(ArrayIDRegisters,IBQuery1.RecordCount);

i:=0;
while not IBQuery1.Eof do
  begin
    ArrayIDRegisters[i].ID:=IBQuery1.FieldByName('IDObj').AsInteger;
    ArrayIDRegisters[i].Info:=TInfo.Create(Self);
    Stream:=TMemoryStream.Create;
    (IBQuery1.FieldByName('blobinfo') as TBlobField).SaveToStream(Stream);
    Stream.Seek(0, soFromBeginning);
    Stream.ReadComponent(ArrayIDRegisters[i].Info);
    Stream.Free;
    Inc(i);
  	IBQuery1.Next
  end;
IBQuery1.Close;
Query2.SQL.Clear;
Query2.SQL.Add('update Objects set info=:ParamInfo where ID=:IDObject');
for i:=0 to Length(ArrayIDRegisters)-1 do
  begin
      begin
        if not IBTransaction2.Active then
          IBTransaction2.StartTransaction;
        Stream:=TMemoryStream.Create;
        Stream.WriteComponent(ArrayIDRegisters[i].Info);
        Stream.Seek(0, soFromBeginning);
        Query2.ParamByName('ParamInfo').LoadFromStream(Stream);
        Query2.ParamByName('IDObject').AsString:=IntToStr(ArrayIDRegisters[i].ID);
        Query2.ExecQuery;
        Stream.Free;
        if IBTransaction2.Active then
          IBTransaction2.Commit
      end;
{здесь вызываецца практически такая же процедура, только она работает с объектами следующего уровня}
  end;
...
Query2.Free
-------------------------------------------------------

Добавлено: 22 июн 2006, 10:14
kdv
Настораживает Page buffers 0
и чем же он тебя настораживает? Может, у него в конфиге database_cache_pages другой стоит. Поосторожней с такими "рекоммендациями", пожалуйста.

Добавлено: 22 июн 2006, 10:16
CCB
DefaultDbCachePages = 2048

Добавлено: 22 июн 2006, 10:18
kdv
if IBTransaction2.Active then
IBTransaction2.Commit
блин, ну ведь уже 10 лет говорят регулярно, что НЕЛЬЗЯ изменение каждой записи завершать коммитом при массовых вставках или обновлениях. Будет МЕДЛЕННО.

А за триггеры такие надо пороть... Что это за триггер UPD_OBJ, в котором торчит 2 update, БЕЗ проверки old <> new?

Добавлено: 22 июн 2006, 10:27
CCB
kdv писал(а):
if IBTransaction2.Active then
IBTransaction2.Commit
блин, ну ведь уже 10 лет говорят регулярно, что НЕЛЬЗЯ изменение каждой записи завершать коммитом при массовых вставках или обновлениях. Будет МЕДЛЕННО.

А за триггеры такие надо пороть... Что это за триггер UPD_OBJ, в котором торчит 2 update, БЕЗ проверки old <> new?
вот оно! даааа, с триггером я лоханулся конкретно.... матьбыевоперемать.... вот это спасибо так спасибо.... большое человеческое спасибо :)

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

Добавлено: 22 июн 2006, 11:13
CyberMax
CCB писал(а):Установка Page buffers не помогла...
Возвращай как было, на 0 =).
kdv писал(а):и чем же он тебя настораживает? Может, у него в конфиге database_cache_pages другой стоит. Поосторожней с такими "рекоммендациями", пожалуйста.
Дмитрий, я же по поводу page buffers ничего не рекомендовал, только насчет page size. Надо же проверить разные варианты причин тормозов, сразу-то сложно определить, в чем проблема...
CCB писал(а):а про транзакции я уже говорил несколько раз - ничего не меняецца, как бы я их не коммитил...
Просто firebird скоростной, да и компы не 486-ые... :D. Но это не повод этим злоупотреблять.

P.S. CREATE INDEX OBJECTS_IDX1 ON OBJECTS (PARENT_ID);
Неверно с логической точки зрения. Вместо этого индекса должен быть foreign key на самого себя.

Добавлено: 22 июн 2006, 12:11
WildSery
CyberMax писал(а):P.S. CREATE INDEX OBJECTS_IDX1 ON OBJECTS (PARENT_ID);
Неверно с логической точки зрения. Вместо этого индекса должен быть foreign key на самого себя.
Не на самого себя, а на таблицу OB.
Кроме того, foreign key не всегда нужен. Может, человеку именованный индекс хочется.

Добавлено: 22 июн 2006, 12:41
CyberMax
WildSery писал(а):Не на самого себя, а на таблицу OB.
Таблицы ob нет - это альяс Objects. Смотри внимательней.
WildSery писал(а):Кроме того, foreign key не всегда нужен.
А про понятие "ссылочная целостность" слышал? Приведи конкретный пример, когда foreign key - не нужен.
WildSery писал(а):Может, человеку именованный индекс хочется.
Ты называешь именем имя "OBJECTS_IDX1" :lol: :lol: :lol:?

Добавлено: 22 июн 2006, 14:46
WildSery
Таблицы ob нет - это альяс Objects. Смотри внимательней.
Тьфу, точно. :oops:
Ты называешь именем имя "OBJECTS_IDX1"
Да, это имя. И к нему можно обратиться. В отличие от "RDB$FOREIGNn", который может поменяться.
А про понятие "ссылочная целостность" слышал? Приведи конкретный пример, когда foreign key - не нужен.
Например, для упрощения репликации - не нужно тщательно следить за порядком вставки объектов.

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

Добавлено: 22 июн 2006, 15:31
CyberMax
WildSery писал(а):Да, это имя. И к нему можно обратиться. В отличие от "RDB$FOREIGNn", который может поменяться.
Бла бла бла. Начиная с FB 1.5, имена индексов внешних ключей по умолчанию "FK_ИМЯТАБЛИЦЫ_ПОЛЕВНЕШНЕГОКЛЮЧА". Собственно, в имени вся информация, которая нужна.
WildSery писал(а):А вообще, я в одной из баз не могу удалить ненужную больше таблицу из-за внешнего ключа. См. мой пост отдельный.
И это товарищи, знаете ли, правильно (С) Горбачев.

Добавлено: 22 июн 2006, 15:38
kdv
короче, если вернуться к проблеме со скоростью записи блобов, то я пока могу посоветовать только одно - поставить AQTime, и посмотреть этим профайлером, где именно тормозить.
Недавно сам нашел одну странность с TFileStream таким образом.

Добавлено: 22 июн 2006, 15:42
WildSery
CyberMax писал(а):Бла бла бла. Начиная с FB 1.5, имена индексов внешних ключей по умолчанию "FK_ИМЯТАБЛИЦЫ_ПОЛЕВНЕШНЕГОКЛЮЧА". Собственно, в имени вся информация, которая нужна.
(с сожалением) Э-э-х. Было бы неплохо.
Жаль, что у меня не каталог журналов, на которые я подписан, а база средних размеров, но всё же 134 таблицы, 2165 процедур и 266 триггеров, которые сами некоторые как приличные процедуры по объёму. И таких баз 37 штук, почти одинаковых по метаданным, но разным по содержанию.
Я не возьму на себя ответственность "взять и переставить" на 1.5.
Проверено - работает - не трогай! (С) не помню.

Возвращаясь к проблеме с блобами - с задачей сохранения свойств компонентов я бы не парился, а закатал их все в ОДИН блоб.

Добавлено: 22 июн 2006, 15:43
CyberMax
CCB сообщал, что зависание именно при выполнении ExecQuery. Подождем, пока он отпишется, что произошло после изменения триггеров.

Добавлено: 23 июн 2006, 02:25
CyberMax
Оффтоплю.
WildSery писал(а):Я не возьму на себя ответственность "взять и переставить" на 1.5.
Если базы будут работать еще несколько лет, лучше все же перейти на 1.5, а потом и на двойку. Чем раньше, тем лучше. Лично у меня из крупных проблем при переходе на 1.5 была только одна - совпадение имен полей в запросах (ну коряво писал на sql). А вообще почитай про миграцию с 1.0 на 1.5 - там описаны все возможные проблемы. Может, не так сложно для тебя это окажется.