Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.10.23;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.003 c
2-1308022626
OlegM
2011-06-14 07:37
2011.10.23
libmysql.dll вылетает если получать данные из Longblob поля


15-1309104565
Weei
2011-06-26 20:09
2011.10.23
Чтение из файла по 2 байта, если размер не кратен 2.


11-1235406790
bert9000
2009-02-23 19:33
2011.10.23
Dinamic menu bar


15-1308850266
Arnolg Mazutneger
2011-06-23 21:31
2011.10.23
внешний HDD греется/не греется


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





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский