Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.10.23;
Скачать: CL | DM;

Вниз

оптимизация добавления в таблицу БД   Найти похожие ветки 

 
handle   (2011-07-08 12:05) [0]


Groups     (Id, Name)
Categories (Id, Name, GroupId);

в таблицу Categories в цикле добавляется порядка 10000-30000 записей, перед добавлением необходимо проверять значение GroupId.


function TAdapter.Add(GroupId: Integer): Integer;
begin
 if not GroupIdIsValid(GroupId) then
   raise Exception.CreateResFmt(@InvalidGroupId, [GroupId]);
 FCategoriesQuery.SQL.Text := Format("INSERT INTO Categories (groupid) VALUES (%d)", [GroupId]);
 FCategoriesQuery.ExecSQL;
end;


function GroupIdExists(GroupId: Integer): Boolean;
begin
 FGroupsQuery.SQL.Text := Format("SELECT group_id FROM groups WHERE group_id = %d", [GroupId]);
 FGroupsQuery.Open;
 Result := FGroupQuery.RowsAffected > 0;
end;


Процесс добавления выполняется очень долго (порядка 15 минут). Если добавление и проверку делать через компонет таблицу (Append, Post, Cancel), поиск (FindKey) на все уходит 3-5 минут. Почему такие затраты времени, если использовать sql-хапросы? Помогите с оптимизацией.


 
RWolf ©   (2011-07-08 12:08) [1]

индексов нет, видимо.


 
Медвежонок Пятачок ©   (2011-07-08 12:10) [2]

тридцать тысяч отдельных селектов с клиента для проверки кажного инсерта.
это сурово.


 
Медвежонок Пятачок ©   (2011-07-08 12:12) [3]

.... да еще и sql без параметров.

нет, пора строить завод по сжиганию программистов.


 
RWolf ©   (2011-07-08 12:15) [4]

то, чем занимается GroupIdExists, называется ссылочная целостность и по уму должно быть прописано в структуре БД, программе этим заниматься незачем.


 
handle   (2011-07-08 12:25) [5]

задача такая, написать api для взаимодействия с бд приложения из 1C. проблема только с функцией добавления - пользователь пробегает по справочнику товаров в 1С и через мой ком-объект, содержащий функцию Add - добавляет товары в БД приложения. тут в любом случае на каждое добавление - отдельный запрос. Как можно оптимизировать затраты.

СУБД - MS Access

GroupIdIsValid нужен для того, чтобы вместо стандартного сообщения об ошибке выводилось мое (это одно из требований в тз).


 
Медвежонок Пятачок ©   (2011-07-08 12:29) [6]

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

Для школьника - в любом случае.
Для программиста - не в любом.
Но для этого надо хоть совсем немного ума.


 
handle   (2011-07-08 12:34) [7]

ну у меня опыта не сколько сколько у вас, пока что ничего лучшего чем использовать TADOTable не придумал.


 
Dennis I. Komarov ©   (2011-07-08 12:44) [8]


> TADOTable не придумал.

ТАБУРЕТКА!!! :)

P.S.
  Поюзайте поиск на предмет сего...


 
Anatoly Podgoretsky ©   (2011-07-08 13:00) [9]


> ну у меня опыта не сколько сколько у вас, пока что ничего
> лучшего чем использовать TADOTable не придумал.

Ужас


 
DiamondShark ©   (2011-07-08 15:42) [10]


> GroupIdIsValid нужен для того, чтобы вместо стандартного
> сообщения об ошибке выводилось мое (это одно из требований
> в тз).

Звезда в шоке.


function TAdapter.Add(GroupId: Integer): Integer;
begin
 try
   FCategoriesQuery.SQL.Text := Format("INSERT INTO Categories (groupid) VALUES (%d)", [GroupId]);
   FCategoriesQuery.ExecSQL;
 except
   raise Exception.CreateResFmt(@InvalidGroupId, [GroupId]);
 end
end;

Например.

Как домашнее задание остаётся проверка на то, что возникшее при исполнении INSERT исключение -- это именно нарушение уникальности.

Следующая ступень просветления -- запрос с параметрами.


 
YurikGL ©   (2011-07-08 19:58) [11]

1) Использовать AdoDataset

2) Проверку уникальности сделать в базе данных (сделать уникальный ключ на соответствующее поле)

3) Делать как-то так
AdoDataset CommandText:="Insert into table (c1,c2) vaules (:v1,:v2)";
For i:=1 to n do begin //это и есть твой цикл
AdoDataset.ParamByName(v1):=SourceMas1[i]
AdoDataset.ParamByName(v2):=SourceMas2[i]
AdoDataSet.Execute
End;

p.s. Делфи под рукой нет, так что синтаксис может быть неверен.


 
YurikGL ©   (2011-07-08 20:00) [12]

Пардон, в коде вставил проверку на ошибку вставки

AdoDataset CommandText:="Insert into table (c1,c2) vaules (:v1,:v2)";
For i:=1 to n do begin //это и есть твой цикл
AdoDataset.ParamByName(v1):=SourceMas1[i]
AdoDataset.ParamByName(v2):=SourceMas2[i]
try
AdoDataSet.Execute
Except
Showmessage("сообщение об ошибке");
end
End;



Страницы: 1 вся ветка

Текущий архив: 2011.10.23;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.007 c
2-1309595561
FolderS
2011-07-02 12:32
2011.10.23
Indy Socket error #0 при post запросе


2-1309782690
Criptonik
2011-07-04 16:31
2011.10.23
Вставка в Memo


2-1309850310
Scott Storch
2011-07-05 11:18
2011.10.23
array of char to string and back


15-1309127349
Германн
2011-06-27 02:29
2011.10.23
Опять WinLock


11-1238511900
DmitryS
2009-03-31 19:05
2011.10.23
непонятная ошибка с MainMenu