Форум программистов, компьютерный форум CyberForum.ru

C++: COM, OLE, ActiveX

Войти
Регистрация
Восстановить пароль
 
akrufar
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
#1

Ускорить работу с формированием запроса - C++ COM

18.06.2016, 12:18. Просмотров 559. Ответов 8
Метки нет (Все метки)

Всем привет!
Помогите решить задачу:
Необходимо добавить через запрос большое количество строк в MySql. Проблему с быстрым добавлением строк за один запрос решается следующим методом:

SQL
1
2
INSERT INTO Provider_Price (A1, A2, .... , An)
VALUES ('текст 11', 'текст 12',  .... , 'текст 1n'), ('текст 2', 'текст 22',  .... , 'текст 2n'), .... , ('текст k1', 'текст k2',  .... , 'текст kn');
т.е. за раз можно добавить много строк, причем скорость в принципе быстрая, чем добавлять построчно.
Проблема сейчас стоит в том, чтобы быстро сформировать этот запрос.
Сейчас формируется через циклический проход по всем строкам из массива строк и добавляется в строку типа AnsiString
C++
1
2
3
4
5
6
AnsiString asSQL;
for(int iRow=1; iRow<=i_RowCount; iRow++){ 
    for(int j = 0; j < slColumnListProviderPrice->Count-1; j++){
        asSQL = asSQL + ", '" + "12345678900987654321" + "'";
    }
}
, где slColumnListProviderPrice - список столбцов таблицы. "12345678900987654321" - данные, которые нужно записать в конкретную ячейку

В данном цикле формируется именно часть ('текст 11', 'текст 12', .... , 'текст 1n'), ('текст 2', 'текст 22', .... , 'текст 2n'), .... , ('текст k1', 'текст k2', .... , 'текст kn').

Так вот при формировании именно таким способом время работы программы при 3000 строках и 18 столбцах составляет примерно в районе 1 минуты, что ОЧЕНЬ долго. когда сама запись в базу уже сформированного запроса занимает меньше 1-2 секунд. Как ускорить формирование такого запроса???

Добавлено через 1 час 0 минут
Для интереса вот время работы:
Время запуска Excel: 3,062 cек.
Время на вычисление кол-ва строк и столбцов: 0,062 cек.
Последний столбец: 18
Последняя строка: 3222
Загрузка данных из Excel в память: 0,375 cек.
Количество загруженных в память строк: 3222
Время на создание запроса: 26,719 cек.
Время на обновление прайса: 0,219 cек.
Общее время импорта: 30,672 cек.

Время на создание запроса включает в себя: поиск позиций в базе по 4 параметрам. Если сам запрос не создавать, то на поиск уходит меньше секунды: Время на поиск товаров: 0,656 cек. При тех же параметрах исходной Excel.
Кто поможет ускорить создание самого запроса???
И второй вопрос: какая максимальная память под запрос может выделяться? Что если в исходном файле будет не 3000 строк и 18 столбцов, а скажем 50 000 строк? + значения ячеек может быть разным. Есть какие-то ограничения? Может стоит добавлять, например, за раз по 10 000 строк ну или как-то контролировать по объему памяти?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.06.2016, 12:18     Ускорить работу с формированием запроса
Посмотрите здесь:

C# Ускорить работу с файлами
PHP Ускорить работу интерпретатора
ускорить работу методов C#
Ускорить работу WebBrowser C#
Как ускорить работу? C++
ускорить работу скрипта PHP БД MySQL
Ускорить работу кода VBA
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
3068 / 1870 / 196
Регистрация: 13.01.2012
Сообщений: 7,120
18.06.2016, 13:55     Ускорить работу с формированием запроса #2
akrufar, покажите настоящий код - формирование строки из обычных 3000 строк не будет занимать столько времени - у вас на месте константы ячейка Эксель?
akrufar
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
18.06.2016, 14:37  [ТС]     Ускорить работу с формированием запроса #3
Так там получается 3220 строк и 18 столбцов, т.е. 57960 ячеек. Ячейки грузятся из Excel в память (вариативный массив) и уже от туда загоняются в запрос. Но время увеличивается не из-за вариативного массива. пробовал вместо данных из массива, просто строку "12345678900987654321" записывать (имитируя данные), все равно время гигантское. т.е. формирование строки из 57960 сток типа "12345678900987654321" занимает время порядка 30 секунд, иногда больше, иногда меньше, в зависимости от загруженности процессора. Но это слишком долго...

боевой код:

C++
1
2
3
4
5
6
7
8
9
for(int iRow=1; iRow<=i_RowCount; iRow++){
    for(int j = 0; j < slColumnListProviderPrice->Count-1; j++){
asSQL = asSQL + ", '" + as_TextWithoutSymbol(
                              VarToStr(v_RangeData.GetElement(iRow,
                                 StrToInt(dmProvider->ds_ProviderPriceSetting->
                                 DataSet->FieldByName(slColumnListProviderPrice->
                                 Strings[j])->Text))) ) + "'";
    }
}
если упростить для восприятия:
C++
1
2
3
4
5
for(int iRow=1; iRow<=i_RowCount; iRow++){
    for(int j = 0; j < slColumnListProviderPrice->Count-1; j++){
        asSQL = asSQL + ", '12345678900987654321'";
    }
}
Добавлено через 4 минуты
Цитата Сообщение от vxg Посмотреть сообщение
у вас на месте константы
На месте 12345678900987654321 ?

Изначально данные из ячейки вариативного массива, но не суть. Если забиваем значением 12345678900987654321. Что в тестовом варианте пробуется, все равно время большое. Скорость падает не из-за обращение к данным, а именно из-за формирования строки из множества маленьких строк

Добавлено через 5 минут
Может есть более быстрые методы работы со строками (сцепления строк)? А то сцеплять строку AnsiString используя + получается долго. Либо может это из-за большого объема самой строки (длина получается большой слишком)?

Добавлено через 8 минут
Для интереса запустил вот такой алгоритм:

C++
1
2
3
4
5
6
7
8
9
10
11
12
Memo1->Lines->Add("Запуск");
//Засекаем время работы  алгоритма 
int i_TimeStart = GetTickCount();
AnsiString asSQL = "";
for(int iRow=1; iRow<=3220; iRow++){
    for(int j = 0; j < 18; j++){
        asSQL = asSQL + ", '12345678900987654321'";
    }
}
//Логирование
Memo1->Lines->Add("Время работы алгоритма: " + FloatToStr((float)(GetTickCount() -
i_TimeStart)/1000.0)+" cек.");
Время работы алгоритма: 28,046 cек.
vxg
Модератор
3068 / 1870 / 196
Регистрация: 13.01.2012
Сообщений: 7,120
18.06.2016, 15:36     Ускорить работу с формированием запроса #4
akrufar, попробуйте выводить в std::stringstream или в достаточный по размерам буфер через sprintf
akrufar
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
18.06.2016, 15:57  [ТС]     Ускорить работу с формированием запроса #5
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Для интереса сделал вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Memo1->Lines->Add("Запуск");
//Засекаем время работы всего алгоритма импорта
int i_TimeStart = GetTickCount();
AnsiString asSQL = "";
 
for(int iRow=1; iRow<=3000; iRow++){
    for(int j = 0; j < 30; j++){
      if(asSQL.Length() < 10000){
        asSQL = asSQL + "12345678900987654321";
      }
      else {
         asSQL = "";
         asSQL = asSQL + "12345678900987654321";
      }
    }
}
//Логирование
Memo1->Lines->Add("Время работы алгоритма: " + FloatToStr((float)(GetTickCount() -
i_TimeStart)/1000.0)+" cек.");
Время работы 0,25 - 0,7 сек.

а если так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
Memo1->Lines->Add("Запуск");
//Засекаем время работы всего алгоритма импорта
int i_TimeStart = GetTickCount();
AnsiString asSQL = "";
 
for(int iRow=1; iRow<=3000; iRow++){
    for(int j = 0; j < 30; j++){
            asSQL = asSQL + "12345678900987654321";
    }
}
//Логирование
Memo1->Lines->Add("Время работы алгоритма: " + FloatToStr((float)(GetTickCount() -
i_TimeStart)/1000.0)+" cек.");
То порядка 50 сек.

Чем объяснить? 0_о Размер AnsiString 2^32-1 = 4294967295 символов, ну никак не переполняется (в нашем случае длинна получается 3000*30*20=1800000), а время ох уж как сильно отличается.. =(

Добавлено через 28 секунд
Цитата Сообщение от vxg Посмотреть сообщение
akrufar, попробуйте выводить в std::stringstream или в достаточный по размерам буфер через sprintf
Надо попробовать... поэксперементирую...
vxg
Модератор
3068 / 1870 / 196
Регистрация: 13.01.2012
Сообщений: 7,120
18.06.2016, 16:01     Ускорить работу с формированием запроса #6
akrufar, объяснение в количестве расширений размера строки я думаю
akrufar
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
18.06.2016, 16:11  [ТС]     Ускорить работу с формированием запроса #7
Пардон, туповат, Не совсем понял...Что означает?
Цитата Сообщение от vxg Посмотреть сообщение
количестве расширений размера строки
т.е. у AnsiString есть какое-то ограничение на количество увеличения самой строки (на количество сцеплений)?
vxg
Модератор
3068 / 1870 / 196
Регистрация: 13.01.2012
Сообщений: 7,120
18.06.2016, 16:50     Ускорить работу с формированием запроса #8
akrufar, не я думаю что при сложении она увеличивается ступенями и из за повторных аллокаций тупит. Если до 10000 наверное аллокация одна две хз
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.06.2016, 14:28     Ускорить работу с формированием запроса
Еще ссылки по теме:

Ускорить работу dcount MS Access
WordPress Ускорить работу сайта
C# Ускорить работу программы
C++ Ускорить работу программы
Ускорить работу программы Visual Basic

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
akrufar
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
22.06.2016, 14:28  [ТС]     Ускорить работу с формированием запроса #9
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от vxg Посмотреть сообщение
akrufar, попробуйте выводить в std::stringstream или в достаточный по размерам буфер через sprintf
Отличный вариант! Все летает Спасибо! остановился на варианте с потоком std::stringstream
Yandex
Объявления
22.06.2016, 14:28     Ускорить работу с формированием запроса
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru