Название: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 14:22 Здравствуйте.
Интересует следующий вопрос: Есть программа которая вытягивает данные из mysql, пока данных в базе было мало всё было ок, но когда объём данных вырос то в процессе получения данных программа подвисает. Подскажите пожалуйста как сделать чтоб на момент подвисания программы появлялось окно с надписью, к примеру "Ждите идёт загрузка...", а после отвисания исчезало. Ни как не могу понять с какой стороны подступится к данной проблеме. Спасибо. Название: Re: Окно загрузки данных Отправлено: Serr500 от Июня 18, 2012, 14:36 Вытягивать данные в отдельном потоке. По окончании процесса генерировать сигнал. В GUI сделать таймер. Если после запуска запроса прошла секунда (100мс, 3 секунды, и т.п. - выбрать по вкусу. Можно и сразу, но при коротких запросах это будет некрасиво.), вывести окошко "Ждите...". Получив сигнал, похерить окошко.
Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 15:38 А без второго потока ни как?
а то я с потоками не работал ни когда. Название: Re: Окно загрузки данных Отправлено: Serr500 от Июня 18, 2012, 15:47 Насколько мне известно, никак.
Название: Re: Окно загрузки данных Отправлено: trot от Июня 18, 2012, 15:50 Цитировать А без второго потока ни как? Никак. Еще надо учитывать, такую особенность, что пользователь может своими действиями не дождавшись одного результата запроса, запустить следующий запрос и такми образом выстроить очередь запросов, ну так далее. Т.е. необходимо продумать политику реакции итерфейса на действия пользователя. Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 18, 2012, 15:58 ... Может быть стоит подумать над оптимизацией кода взаимодействия программы с БД? Часто совершенно не имеет смысла переливать всю информацию из таблиц в память. Или в Вашем случае нужно именно так?Есть программа которая вытягивает данные из mysql, пока данных в базе было мало всё было ок, но когда объём данных вырос то в процессе получения данных программа подвисает. ... Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 16:44 ... Может быть стоит подумать над оптимизацией кода взаимодействия программы с БД? Часто совершенно не имеет смысла переливать всю информацию из таблиц в память. Или в Вашем случае нужно именно так?Есть программа которая вытягивает данные из mysql, пока данных в базе было мало всё было ок, но когда объём данных вырос то в процессе получения данных программа подвисает. ... Полученные данные затягиваются в модель в которой из них строится дерево, пробовал реализовать fechMore() но в результате помимо подвисания при получении данных в начале, получил ещё подвисания при разворачивании каждой ветки дерева. Вот и решил что самым оптимальным будет окошко с уведомлением, иначе кажется что прога тупо зависла. Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 16:46 Спасибо всем за ответы, буду учить потоки :)
Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 18, 2012, 17:21 Мне кажется, что вьюха всё же должна более плотно работать с моделью. Как-то в пустую тратятся ресурсы. Действительно, ну зачем гнать из модели во вьюху 1000 строк, если максимум штук 100 будет выведено. Если пользователь двинет ползунок прокрутки, значит только тогда и подгружать следующую порцию данных. А может так статься, что ползунок сместится на незначительное расстояние, что будет требовать ещё меньшего количества подгружаемых данных. В итоге - минимум тормозов, если таковые вообще возникнут.
А если ещё взглянуть в сторону веба, то там подобные проблемы решаются при помощи пагинации, часто вкупе с аяксом. Другими словами, выглядит более рационально. В чём я не прав? Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 17:31 Мне кажется, что вьюха всё же должна более плотно работать с моделью. Как-то в пустую тратятся ресурсы. Действительно, ну зачем гнать из модели во вьюху 1000 строк, если максимум штук 100 будет выведено. Если пользователь двинет ползунок прокрутки, значит только тогда и подгружать следующую порцию данных. А может так статься, что ползунок сместится на незначительное расстояние, что будет требовать ещё меньшего количества подгружаемых данных. В итоге - минимум тормозов, если таковые вообще возникнут. На данном этапе тормоза возникают именно при выборке данных из БД, а на счёт постепенной загрузки данных во вьюху, это как? У меня есть модель, я выбираю данные из БД, потом эти данные выстраиваю в дерево и как потом мне передавать во вьюху не все данные, я что то не понимаю, можно пример? Название: Re: Окно загрузки данных Отправлено: mutineer от Июня 18, 2012, 17:36 У меня есть модель, я выбираю данные из БД, потом эти данные выстраиваю в дерево и как потом мне передавать во вьюху не все данные, я что то не понимаю, можно пример? Вьюха ведь у модели спрашивает не все данные разом, а только попадающие на экран. Вот и не грузи все остальные сразу, а только когда вьюха их запросит. Или, что еще лучше, загружай немножко больше, чем нужно вьюхе, и подгружай по мере приближения запросов к границе загруженных данных Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 18, 2012, 17:54 На данном этапе тормоза возникают именно при выборке данных из БД, а на счёт постепенной загрузки данных во вьюху, это как? Если данных очень много, то вполне ожидаемо, что будут тормоза. Под это дело выделяется память. И помимо собственно самих табличных данных, выделяется память и под всякого рода "служебную" инфу. Всё это безусловно нужно, но нужно ли всё сразу, вот в чём вопрос.У меня есть модель, я выбираю данные из БД, потом эти данные выстраиваю в дерево и как потом мне передавать во вьюху не все данные, я что то не понимаю, можно пример? Боюсь, что решения у меня для Вас нет. Здесь нужен гуру кьютишного Model/View (я больше в другой области). Просто когда-то давно, ещё на первых версиях четвёрки (Qt4) я делал фронтэнд к менеджеру пакетов для Linux. Тоже был вьювер, тоже была модель, тоже куча позиций, измеряемых десятками тысяч. Единственное, в роли БД выступало API пакетного менеджера, но суть задачи сводилась к тому же, что и у Вас. Стоило мне всех их загружать разом, так сразу возникали жуткие GUI-тормоза. Поэтому я сделал решение, логику которого описал в посте выше, т.е. частичную подгрузку. И всё стало шикарно работать. Во время подгрузки новых позиций, если пользователь шнырял ползунком прокрутки туда-сюда, нужные итемы всегда довольно быстро подгружались.Как я это сделал - не помню, да и к сожалению код у меня не сохранился. Вроде там была реализована плотная связка между моделью и вьювером, то есть каждый знал о состоянии каждого. Конечно, это вроде как нарушение принципа Qt MV, но такое частное решение позволило обойтись без потоков и работало весьма сносно. Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 18, 2012, 17:55 Вьюха ведь у модели спрашивает не все данные разом, а только попадающие на экран Тем более тогда непонятно, почему возникла эта проблема... Название: Re: Окно загрузки данных Отправлено: mutineer от Июня 18, 2012, 18:04 Вьюха ведь у модели спрашивает не все данные разом, а только попадающие на экран Тем более тогда непонятно, почему возникла эта проблема... Конечно непонятно - кода ведь нет Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 20:02 Вьюха ведь у модели спрашивает не все данные разом, а только попадающие на экран Тем более тогда непонятно, почему возникла эта проблема... Конечно непонятно - кода ведь нет Исходник модели .h - http://gitorious.org/workerplace/workerplace/blobs/master/headers/devicemodel.h .cpp - http://gitorious.org/workerplace/workerplace/blobs/master/source/devicemodel.cpp Исходник класса дерева .h - http://gitorious.org/workerplace/workerplace/blobs/master/headers/treeitem.h .cpp - http://gitorious.org/workerplace/workerplace/blobs/master/source/treeitem.cpp Исходник класса управления модели .h - http://gitorious.org/workerplace/workerplace/blobs/master/headers/devicemodelcontrol.h .cpp - http://gitorious.org/workerplace/workerplace/blobs/master/source/devicemodelcontrol.cpp Ну и виджет который использует модель .h - http://gitorious.org/workerplace/workerplace/blobs/master/headers/device.h .cpp - http://gitorious.org/workerplace/workerplace/blobs/master/source/device.cpp На данном этапе тормоза возникают именно при выборке данных из БД, а на счёт постепенной загрузки данных во вьюху, это как? Если данных очень много, то вполне ожидаемо, что будут тормоза. Под это дело выделяется память. И помимо собственно самих табличных данных, выделяется память и под всякого рода "служебную" инфу. Всё это безусловно нужно, но нужно ли всё сразу, вот в чём вопрос.У меня есть модель, я выбираю данные из БД, потом эти данные выстраиваю в дерево и как потом мне передавать во вьюху не все данные, я что то не понимаю, можно пример? Боюсь, что решения у меня для Вас нет. Здесь нужен гуру кьютишного Model/View (я больше в другой области). Просто когда-то давно, ещё на первых версиях четвёрки (Qt4) я делал фронтэнд к менеджеру пакетов для Linux. Тоже был вьювер, тоже была модель, тоже куча позиций, измеряемых десятками тысяч. Единственное, в роли БД выступало API пакетного менеджера, но суть задачи сводилась к тому же, что и у Вас. Стоило мне всех их загружать разом, так сразу возникали жуткие GUI-тормоза. Поэтому я сделал решение, логику которого описал в посте выше, т.е. частичную подгрузку. И всё стало шикарно работать. Во время подгрузки новых позиций, если пользователь шнырял ползунком прокрутки туда-сюда, нужные итемы всегда довольно быстро подгружались.Как я это сделал - не помню, да и к сожалению код у меня не сохранился. Вроде там была реализована плотная связка между моделью и вьювером, то есть каждый знал о состоянии каждого. Конечно, это вроде как нарушение принципа Qt MV, но такое частное решение позволило обойтись без потоков и работало весьма сносно. Жаль что у вас не осталось исходников было бы интересно взлянуть на реализацию, думаю не только мне :). Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 18, 2012, 20:07 ... Да не, раз говорят, что вьюха забирает с модели только нужные строки, значит смысл мой пример теряет. Может быть тогда это не было реализовано, а только спустя время. Я не помню, да и не суть. Значит Вам нужно лишь что-то подправить в модели, чтобы было тип-топ :)Жаль что у вас не осталось исходников было бы интересно взлянуть на реализацию, думаю не только мне :). Название: Re: Окно загрузки данных Отправлено: mutineer от Июня 18, 2012, 20:13 У меня вытекли глаза от этой простыни... Сегодня читать точно не буду, может завтра
Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 20:16 У меня вытекли глаза от этой простыни... Сегодня читать точно не буду, может завтра :) Да не вопрос, буду рад совету, заранее прошу прощения за то что коментов в коде нет, это мой первый проект и пишу его сам, собственно процесс обучения и написания идёт параллельно. Название: Re: Окно загрузки данных Отправлено: Bepec от Июня 18, 2012, 20:23 Поток нужен. Обязательно. Собственно что можно посоветовать.
Простые варианты: 1) при перемещении ползунка отсчитывать позицию. Потом запрашивать лишь видимое число элементов. Т.е. максимум для 24 дюймового монитора - где то от 500 до 1,5к строк. 2) использовать Q*SqlModel. Насколько я помню, она прекрасно оптимизирована и у неё отсутствует описанный недостаток. 3) ну хз. Самый кривой способ - кешировать сразу все записи. В самом начале. Т.е. делаем окошко ожидания и загружаем сразу всё. Сколько-то там времени займёт, зато потом будет летать, если хватит оперативки :D PS и маленький совет. Можно вместо окошка ожидания, выводить гифку загрузки аля Ютуб посередине Q*View. Гораздо понятнее пользователю и читать ненадо :D Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 18, 2012, 20:36 Поток нужен. Обязательно. Собственно что можно посоветовать. Простые варианты: 1) при перемещении ползунка отсчитывать позицию. Потом запрашивать лишь видимое число элементов. Т.е. максимум для 24 дюймового монитора - где то от 500 до 1,5к строк. 2) использовать Q*SqlModel. Насколько я помню, она прекрасно оптимизирована и у неё отсутствует описанный недостаток. 3) ну хз. Самый кривой способ - кешировать сразу все записи. В самом начале. Т.е. делаем окошко ожидания и загружаем сразу всё. Сколько-то там времени займёт, зато потом будет летать, если хватит оперативки :D PS и маленький совет. Можно вместо окошка ожидания, выводить гифку загрузки аля Ютуб посередине Q*View. Гораздо понятнее пользователю и читать ненадо :D Спасибо :), буду учить потоки. Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 18, 2012, 20:48 Верес, Вы порвали в клочья последнюю надежду
Название: Re: Окно загрузки данных Отправлено: Bepec от Июня 18, 2012, 20:50 Работа у меня такая. Там снайпер, тут эльф, здесь программист и разрушитель надежд, что всё так просто :D
Название: Re: Окно загрузки данных Отправлено: Syveren от Июня 19, 2012, 10:35 А что если хранить только ключи в модели. А сам запрос на получение данных делать в методе QAbstractModel::data().
Я дулал так для списка - работало на ура. Данный способ увеличил быстродействие загрузки с 2 минут, до 2 секунд И ещё зависит от Субд подойдёт ли вам этот способ или нет. Код
Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 19, 2012, 10:42 А что если хранить только ключи в модели. А сам запрос на получение данных делать в методе QAbstractModel::data(). С одной стороны - хорошо, а с другой - будет множество мелких запросов к БД. Подход как у ORM.Я дулал так для списка - работало на ура. Название: Re: Окно загрузки данных Отправлено: Syveren от Июня 19, 2012, 10:59 Цитировать С одной стороны - хорошо, а с другой - будет множество мелких запросов к БД. Подход как у ORM Всё зависит от использоваемого драйвера SQL. Для драйвера QPSQL данный подход не принёс ничего ценного (он и без этих наворотов работал быстро). Но при использовании QODBC было колосальное ускорение. Название: Re: Окно загрузки данных Отправлено: Syveren от Июня 19, 2012, 11:03 Я и начал использовать данный подход, так как из-за смены СУБД, загрука стала вдруг такой медленной, что ни в какие ворота не лезло.
Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 19, 2012, 11:21 Вот мне это всё непонятно. Сразу скажу, что с БД в Qt практически не занимался. Можно сказать, что опыт на нуле по этой теме. Работал всё больше в вебе, да и только с мускулом (MySQL).
По логике, если сравнить два подхода, то в первом: А. парсинг мускулом запроса - O(1); Б. возврат данных большим куском - O(n); ... а во втором появляется зависимость от кол-ва записей: А. парсинг мускулом запроса - O(1); Б. возврат данных маленьким куском - O(1). При этом, второй подход выполняется n раз. Дополнительно: в первом варианте можно использовать транзакцию, которая гарантирует существенное снижение длительности выполнения пункта Б. Вопрос: что будет работать быстрее? Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 19, 2012, 13:11 А что если хранить только ключи в модели. А сам запрос на получение данных делать в методе QAbstractModel::data(). Я дулал так для списка - работало на ура. Данный способ увеличил быстродействие загрузки с 2 минут, до 2 секунд И ещё зависит от Субд подойдёт ли вам этот способ или нет. Интересный вариант, надо будет попробовать. Дополнительно: в первом варианте можно использовать транзакцию, которая гарантирует существенное снижение длительности выполнения пункта Б. Вопрос: что будет работать быстрее? Ни попробуешь не узнаешь :). А на счёт транзакции можно подробней, я просто с ними не работал, каким образом транзакция уменьшает время запроса на выборку, я всегда думал что транзакция нужна для отката изменений и блокировки таблицы на время работы с ней. Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 19, 2012, 14:37 ... За счёт одноразового обновления индексов у таблицы, одноразовых блокировки и предоставления доступа.А на счёт транзакции можно подробней, я просто с ними не работал, каким образом транзакция уменьшает время запроса на выборку, я всегда думал что транзакция нужна для отката изменений и блокировки таблицы на время работы с ней. Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 19, 2012, 15:17 А как mysql организовать транзакцию для выборки данных?
На сколько я знаю для обновления таблицы используется BEGIN; для начала транзакции и COMMIT; для внесения сделанных изменений или ROLLBACK для их отката. Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 19, 2012, 15:32 Для начала скажите, какой из движков Вы используете у таблицы. Если MyISAM, то он транзакции как таковые не поддерживает. У него каждая операция - есть отдельная транзакция. Если InnoDB, то транзакции имеет смысл использовать однозначно.
Название: Re: Окно загрузки данных Отправлено: Syveren от Июня 19, 2012, 16:35 QSqlDatabase db;
db.driver ()->hasFeature (QSqlDriver::Transactions); - поддерживаются ли транзакции Если да, то удобно использовать db.transaction(); db.rollback();db.commit(); Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 19, 2012, 16:46 Для начала скажите, какой из движков Вы используете у таблицы. Если MyISAM, то он транзакции как таковые не поддерживает. У него каждая операция - есть отдельная транзакция. Если InnoDB, то транзакции имеет смысл использовать однозначно. использую InnoDB QSqlDatabase db; db.driver ()->hasFeature (QSqlDriver::Transactions); - поддерживаются ли транзакции Если да, то удобно использовать db.transaction(); db.rollback();db.commit(); насколько я знаю для mysql транзакции поддерживаются Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 19, 2012, 17:00 использую InnoDB Зачастую правильное решение.насколько я знаю для mysql транзакции поддерживаются Да, но не всеми движками. В мускуле их много. InnoDB как раз поддерживает. И для него транзакции нужны, иначе производительность отличается в худшую сторону от того же MyISAM.Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 20, 2012, 09:41 Попробовал сделать транзакцию на выборку данных,
сначала выполнил два запроса в самой mysql 1. SELECT * FROM table; 2. BEGIN; SELECT * FROM table; COMMIT; 2-й реально быстрей отрабатывает, но при вставке второго запроса в query.exec(), содержимое query оказывается пустым, хотя в самой mysql всё ок. В чём может быть проблема, или я что-то делаю не так? Название: Re: Окно загрузки данных Отправлено: alexis031182 от Июня 20, 2012, 09:53 Может быть надо запрос этот разбить на три query.exec()
Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 20, 2012, 13:20 на 2-а :)
BEGIN и всё остальное Название: Re: Окно загрузки данных Отправлено: vovan1982 от Июня 20, 2012, 13:28 спасибо всем за помощь, после оптимизации запросов и использования транзакций удалось в разы сократить время загрузки, теперь вместо 10 сек. загрузка идёт 3 сек.
Без второго потока действительно не обойтись, попытался использовать qApp->processEvents(); но использование gif анимации в таком случае не возможно, анимация начинает работать только после полной загрузки виджета, а если у честь что при полной загрузке виджета окно с анимацией закрывается то смысла в анимации попросту нет. Так что пошёл разбираться с потоками :). Ещё раз спасибо за помощь. |