Оптимизация работы с БД

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Дмитрий Б.
Сообщения: 56
Зарегистрирован: 05 дек 2007, 18:09

Оптимизация работы с БД

Сообщение Дмитрий Б. » 29 окт 2010, 12:36

Здраствуйте.

Столкнулся с такой проблеммой:

Имеются n кол-во *.xls (Excel) файлов. Каждый файл могет содержать от 100 до 10000 строк.
Поочередно из этих файлов производится построчное считывание значений ячеек каждой строки (кол-во ячеек в строке до 10 шт) и запись их в БД.

Функция для получения значения ячейки:

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

Variant __fascall TForm:fromExcelCell(int Row, int Column)
{
    try{ Variant result, cur;
           cur = Sh.OlePropertyGet("Cells", Row, Column);
           result = cur.OlePropertyGet("Value");
           return result;
        } catch(...) {;}
    return 0;
}
Функция для записи полученных из fromExcelCell(int Row, int Column) значений в БД:

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

...
for(int i=0; i<CountRowExcel; i++)
{
   IBDataSet->Insert();
   IBDataSet->FieldByName("1")->AsString = fromExcelCell(i+1, col_1);
   ...
   IBDataSet->FieldByName("n")->AsString = fromExcelCell(i+1, col_n);
   IBDataSet->Post();
}
Все какбы работает, но появилась следующая проблема:

В начале заполнения БД (в БД нет записей) процесс занесения записей протекает быстро (например 3500 строк заносится в БД примерно за 10 мин)(<строка в *.xls [ячейка_1],[ячейка_2],[ячейка_3]...[ячейка_N]> == <запись в БД [поле_1],[поле_2],[поле_3]...[поле_N]>).
Но с увеличением количества записей в БД до 45000 скорость записи данных в БД заметно снижается (из 6000 строк заносится в БД всего 400 строк и это только за 1 час) при этом процесс ibserver.exe дает загрузку центрального процессора 99 %.

Подскажите пожалуйста, что-бы это могло быть и как это можно обойти? Есть-ли способ как можно оптимизировать?.

Большое спасибо.

С Уважением, Дмитрий.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: Оптимизация работы с БД

Сообщение Dimitry Sibiryakov » 29 окт 2010, 14:33

Нанять программиста, который читал это. И, соответственно, уволить того, кто использовал для импорта TIBDataSet.

Дмитрий Б.
Сообщения: 56
Зарегистрирован: 05 дек 2007, 18:09

Re: Оптимизация работы с БД

Сообщение Дмитрий Б. » 03 ноя 2010, 17:33

Dimitry Sibiryakov писал(а):Нанять программиста, который читал это. И, соответственно, уволить того, кто использовал для импорта TIBDataSet.
Большое спасибо, Dimitry Sibiryakov за наводку.

Взял компонент TIBSQL - после чего скорость импорта возрасла в сотни раз (теперь 60500 записей заносятся за 13-15 мин).

Вот часть кода:

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

    FormSearch->IBSQL1->Close();
    FormSearch->IBSQL1->SQL->Clear();
    FormSearch->IBSQL1->SQL->Text = "insert into TB_PRICE (NUMB, NAME, MARKA, MODEL, COMP_NAME, MN_IN, MN_ROZN, MN_POST, OSTAT, UP_DATE) values ('" + strNumb + "', '" + strName + "', '" + strMarka + "', '" + strModel + "', '" + CompName + "', '" + strMN_IN + "', '" + strMN_ROZN + "', '" + strMN_POST + "', '" + strOSTAT + "', '" + ((AnsiString)DateToStr(Now()))+ "')";
    FormSearch->IBSQL1->ExecQuery();
    FormSearch->IBSQL1->Close();
Единственный минус - нужно отслеживать длину переменных str***** во избежания переполнения зпдпнного размера поля в БД, что разрешается str****.SubString(0,<заданная длина поля БД>);

С Уважением, Дмитрий.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: Оптимизация работы с БД

Сообщение Dimitry Sibiryakov » 04 ноя 2010, 14:52

Вторая наводка: уволить "программиста", который не слышал про параметризованные запросы.

Дмитрий Б.
Сообщения: 56
Зарегистрирован: 05 дек 2007, 18:09

Re: Оптимизация работы с БД

Сообщение Дмитрий Б. » 09 ноя 2010, 20:38

Программист все осознал и обещал исправиться :-)

Кстати параметризация позволила исключить ошибку возникающую при обычном формировании запроса (если в вставляемом тексте присутствует символ (').

C Уважением.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Оптимизация работы с БД

Сообщение kdv » 10 ноя 2010, 08:46

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

Ответить