91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
1

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

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

Author24 — интернет-сервис помощи студентам
Всем привет!
Помогите решить задачу:
Необходимо добавить через запрос большое количество строк в 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 строк ну или как-то контролировать по объему памяти?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.06.2016, 12:18
Ответы с готовыми решениями:

ускорить работу запроса
Добрый день! сделал рабочий запрос, но время его выполнения занимает около трех с половиной минут...

Проблема с формированием запроса
Уважаемые программисты прошу вашей подсказки. Есть БД SQLite. С помощью запроса: SELECT , ,...

Ускорить работу программы
суть такова, на форме имеется два текст бокса и кнопка, в первый текст бокс вводится набор букв, во...

Как ускорить работу?
Прога ещё не доработана, сейчас интересует именно графический режим, когда нажимается клавиша 1-4...

8
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,422
18.06.2016, 13:55 2
akrufar, покажите настоящий код - формирование строки из обычных 3000 строк не будет занимать столько времени - у вас на месте константы ячейка Эксель?
0
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ек.
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,422
18.06.2016, 15:36 4
akrufar, попробуйте выводить в std::stringstream или в достаточный по размерам буфер через sprintf
1
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
18.06.2016, 15:57  [ТС] 5
Лучший ответ Сообщение было отмечено vxg как решение

Решение

Для интереса сделал вот так:

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
Надо попробовать... поэксперементирую...
1
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,422
18.06.2016, 16:01 6
akrufar, объяснение в количестве расширений размера строки я думаю
1
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
18.06.2016, 16:11  [ТС] 7
Пардон, туповат, Не совсем понял...Что означает?
Цитата Сообщение от vxg Посмотреть сообщение
количестве расширений размера строки
т.е. у AnsiString есть какое-то ограничение на количество увеличения самой строки (на количество сцеплений)?
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,422
18.06.2016, 16:50 8
akrufar, не я думаю что при сложении она увеличивается ступенями и из за повторных аллокаций тупит. Если до 10000 наверное аллокация одна две хз
0
91 / 3 / 2
Регистрация: 19.05.2016
Сообщений: 38
22.06.2016, 14:28  [ТС] 9
Лучший ответ Сообщение было отмечено vxg как решение

Решение

Цитата Сообщение от vxg Посмотреть сообщение
akrufar, попробуйте выводить в std::stringstream или в достаточный по размерам буфер через sprintf
Отличный вариант! Все летает Спасибо! остановился на варианте с потоком std::stringstream
1
22.06.2016, 14:28
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.06.2016, 14:28
Помогаю со студенческими работами здесь

Ускорить работу функций
Здравствуйте. Не подскажете как можно ускорить работу функций в цикле? А то линия получается...

Ускорить работу интерпретатора
Очень тяжелый скрипт на 2 часа при работе загружает проц только на 10-15%. Есть ли какие-то...

Ускорить работу dcount
Имеется таблица1. Необходимо найти в этой таблице в поле связь самое большое натуральное число,...

ускорить работу скрипта
Друзья - php скрипт выполняется более 400 секунд! Подскажите что можно подправить - что бы...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

Новые блоги и статьи
Интеграция Arduino и ChatGPT: Практическое руководство
InfoMaster 16.01.2025
В современную эпоху технологических инноваций интеграция искусственного интеллекта с микроконтроллерами открывает принципиально новые возможности для создания умных устройств и автоматизированных. . .
Как создать робота, управляемого ChatGPT
InfoMaster 16.01.2025
Концепция проекта В современную эпоху искусственный интеллект и робототехника становятся все более доступными для энтузиастов и разработчиков. Создание роботизированной руки, управляемой ChatGPT,. . .
Как создать ChatGPT бота в Telegram на Python
InfoMaster 16.01.2025
В современном мире технологии искусственного интеллекта становятся все более доступными для разработчиков, открывая новые возможности для создания умных и интерактивных приложений. Одним из самых. . .
Машинное обучение с помощью Python
InfoMaster 16.01.2025
Машинное обучение стало неотъемлемой частью современных технологий, позволяя компьютерам учиться на основе данных и принимать решения без явного программирования. В сочетании с языком. . .
Использование связки C# и PHP в корпоративной разработке и микросервисной архитектуре
InfoMaster 16.01.2025
Введение в интеграцию C# и PHP В современной корпоративной разработке все чаще возникает потребность в создании гибких и масштабируемых решений, способных эффективно решать широкий спектр. . .
Как использовать Kerio дома для управления сетью и пользователями
InfoMaster 16.01.2025
Использование технологий для улучшения повседневной жизни стало неотъемлемой частью современного быта. Одной из таких технологий является Kerio — мощный инструмент для управления сетью и. . .
Есть ли будущее у DVD и Blu-ray?
InfoMaster 16.01.2025
В эпоху стремительного развития цифровых технологий и повсеместного распространения потоковых сервисов вопрос о будущем физических носителей информации становится все более актуальным. Особенно остро. . .
Как проводить научные вычисления на Python
InfoMaster 15.01.2025
Python стал одним из наиболее востребованных языков программирования в области научных вычислений благодаря своей простоте, гибкости и обширной экосистеме специализированных библиотек. Научные. . .
Создание игры типа Minecraft на PyGame/Python: пошаговое руководство
InfoMaster 15.01.2025
В данном руководстве мы рассмотрим процесс создания игры в стиле Minecraft с использованием библиотеки PyGame на языке программирования Python. Этот проект идеально подходит как для начинающих. . .
Как создать свою первую игру в стиле Doom на Unreal Engine
InfoMaster 15.01.2025
Разработка шутера от первого лица в стиле классического Doom представляет собой увлекательное путешествие в мир игрового программирования, где сочетаются творческий подход и технические навыки. . . .
Параллельное программировани­е: основные технологии и принципы
InfoMaster 15.01.2025
Введение в параллельное программирование Параллельное программирование представляет собой фундаментальный подход к разработке программного обеспечения, который позволяет одновременно выполнять. . .
Как написать микросервис на C# с Kafka, MediatR, Redis и GitLab CI/CD
InfoMaster 15.01.2025
В современной разработке программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот подход позволяет разделить сложную систему. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru