![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Очень медненный Append в таблицу Firebird-a
DelphiN! © (2006-05-29 09:49:00)Когда в таблице было мало записей добавление в базу происходило моментально, теперь чтобы добавить одну звпись в базу необходимо более 2х секунд времени!
Таблица следующая :
CASEBASE (
COMP_ VARCHAR(20) CHARACTER SET NONE,
SUMM_ FLOAT,
TIMES_ DATE,
TIMEPO_ DATE,
PERIOD_ INTEGER,
USLUGA_ VARCHAR(20) CHARACTER SET NONE,
TIME_ DATE,
PRIM_ VARCHAR(20) CHARACTER SET NONE,
USER_ VARCHAR(20) CHARACTER SET NONE,
ID_ INTEGER NOT NULL
);
Поле ID_ - уникальное индексное поле, по полю TIME_ также создан индекс
Добавляю данные следующим образом
CASEBASE.Append;
CASEBASE.FieldByName('COMP_').AsString := IpToName(IP);
CASEBASE.FieldByName('SUMM_').AsFloat := RoundTo(Summ, -2);
CASEBASE.FieldByName('Prim_').AsString := prim;
CASEBASE.FieldByName('TimeS_').AsDateTime := TimeS;
CASEBASE.FieldByName('TimePo_').AsDateTime := TimePo;
CASEBASE.FieldByName('Period_').AsInteger := GetCurrentPeriod;
CASEBASE.FieldByName('TIME_').AsDateTime := now;
CASEBASE.FieldByName('User_').AsString := UserName;
CASEBASE.FieldByName('Usluga_').AsString := Usluga;
CASEBASE.Post;
IbTransaction.CommitRetaining;
как уменьшить время добавления записи в таблицу?
Desdechado (2006-05-29 13:29:00) [1]да, и обращение к параметрам пономеру быстрее, чем по имени
Desdechado (2006-05-29 13:28:00) [2]Romkin © (29.05.06 13:17) [16]
Также есть подозрения, что при этом все записи отображаются где-нибудь в гриде...
Кстати, один коммит не 100-1000 записей гораздо производительнее, чем по коммиту на запись.
А еще я бы вынес из цикла вызовы функций, например, IpToName(IP), RoundTo(Summ, -2), GetCurrentPeriod
Romkin (2006-05-29 13:17:00) [3]Очень глупо вообще выбирать 100000 записей. Даже чтобы добавить еще одну :)
Набор скорее всего переоткрывается.
Необходима модификация: выборка только тех записей, что нужны, а если нужна только вставка - так и делать только вставку через insert.
Сергей М. (2006-05-29 11:13:00) [4]
> когда CommitRetaining то просто мерцает, вроде как закрывается
> и открывается
>
Все-таки ситуация похожа на переоткрытие НД.
CommitRetaining не переоткрывает НД - выполняется подтверждение ТА с сохранением открытого НД.
Посмотри в лог IBSQLMonitor - если переоткрытие НД происходит, это будет отражено в логе.
DelphiN! (2006-05-29 10:35:00) [5]Сергей М. © (29.05.06 10:22) [12]
SELECT * FROM CASEBASE
Select
COMP_,
SUMM_,
TIMES_,
TIMEPO_,
PERIOD_,
USLUGA_,
TIME_,
PRIM_,
USER_
from CASEBASE
where
ID_ = :ID_
update CASEBASE
set
COMP_ = :COMP_,
PERIOD_ = :PERIOD_,
PRIM_ = :PRIM_,
SUMM_ = :SUMM_,
TIME_ = :TIME_,
TIMEPO_ = :TIMEPO_,
TIMES_ = :TIMES_,
USER_ = :USER_,
USLUGA_ = :USLUGA_
where
ID_ = :OLD_ID_
insert into CASEBASE
(COMP_, PERIOD_, PRIM_, SUMM_, TIME_, TIMEPO_, TIMES_, USER_, USLUGA_)
values
(:COMP_, :PERIOD_, :PRIM_, :SUMM_, :TIME_, :TIMEPO_, :TIMES_, :USER_,
:USLUGA_)
delete from CASEBASE
where
ID_ = :OLD_ID_
DelphiN! (2006-05-29 10:28:00) [6]Sergey13 © (29.05.06 10:17) [8]
2 [7] DelphiN! © (29.05.06 10:14)
И что в нем в проперти SQL?
IbDataSet.SelectSQL.Text := 'SELECT * FROM CASEBASE WHERE ...';
procedure CASEBASEAfterPost(DataSet: TDataSet);
begin
IBTransaction1.CommitRetaining;
end;
>Переоткрытия нет, так как CommitRetaining сам переоткрывает
Это как?
Ну ведь когда Commit делаешь, то таблица закрывается, а когда CommitRetaining то просто мерцает, вроде как закрывается и открывается
Сергей М. (2006-05-29 10:22:00) [7]Тогда приводи тексты Insert/Select/RefreshSQL ..
DelphiN! (2006-05-29 10:21:00) [8]Сергей М. © (29.05.06 10:18) [9]
Нет, Commit один вызывается(в AfterPost), это я его на форуе вставил просто, чтобы не приводить обработчик AfterPost
DelphiN! (2006-05-29 10:19:00) [9]Если вместо CommitRetaining использовать просто Commit, то время добавления записи практически не уменьшается ..
Сергей М. (2006-05-29 10:18:00) [10]
> DelphiN! © (29.05.06 10:14) [7]
А зачем аж целых два коммита ?
Первый - сразу после после вызова тобой Post, второй - в обработчике AfterPost()
?
Sergey13 (2006-05-29 10:17:00) [11]2 [7] DelphiN! © (29.05.06 10:14)
>TIbDataSet.
И что в нем в проперти SQL?
>Переоткрытия нет, так как CommitRetaining сам переоткрывает
Это как?
DelphiN! (2006-05-29 10:14:00) [12]Sergey13 © (29.05.06 10:12) [6]
TIbDataSet. Переоткрытия нет, так как CommitRetaining сам переоткрывает
Sergey13 (2006-05-29 10:12:00) [13]2Sergey13 © (29.05.06 09:56) [2]
>CASEBASE это имя таблицы.
Это я догадался. 8-) Я имел в виду в программе это TTable или TIBDataset? Нет ли переоткрытия после Поста?
DelphiN! (2006-05-29 10:08:00) [14]Сергей М. © (29.05.06 10:01) [3]
Ну это то понятно что CommitRetaining тормозит, только ведь он Append выполняет, а из индексов по полю ID_ первичный уникальный ключ создан и поле TIME_ индексное.
Размер таблицы CASEBASE около 100 000 записей, всего в базе данных около 1 000 000 записей, занимает БД около 500 мб.
DelphiN! (2006-05-29 10:04:00) [15]Sergey13 © (29.05.06 09:56) [2]
CASEBASE это имя таблицы.
Стоит тригер на BeforeInsert на поле ID_, который добавляет в него уникальный номер.
Из обработчиков в Датасете стоит только в AfterPost IbTransaction.CommitRetaining;
Сергей М. (2006-05-29 10:01:00) [16]Append по идее "тормозить" не может - скорее уж Post и/или CommitRetaining
Для начала замени Append на Insert (хотя это и не принципиально).
Какие индексы существуют в таблице CASEBASE ?
Sergey13 (2006-05-29 09:56:00) [17]Что такое CASEBASE?
Какие-нибудь тригеры висят на таблице? Обработчики на датасете?
DelphiN! (2006-05-29 09:52:00) [18]Backup\Restore не помогают