Работа с подготовленными запросами (QSqlQuery::prepare) (Firebird 2.1), оптимизация запросов, кэширование, транзакции |
Здравствуйте, гость ( Вход | Регистрация )
Работа с подготовленными запросами (QSqlQuery::prepare) (Firebird 2.1), оптимизация запросов, кэширование, транзакции |
Steklova Olga |
3.2.2014, 19:23
Сообщение
#1
|
Участник Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: 4 |
Всем привет
Пишу класс для работы с БД. Написала метод класса, выполняющий подключение к БД. Написала метод класса, выполняющий вставку записей в таблицу. В таком виде он работает. Метод insertToDB() в процессе работы программы вызывается многократно.В результате, каждый раз подготавливается один и тот же запрос. Как сделать так, чтобы запрос подготавливался только один раз? Я хотела вынести подготовку запроса в другой метод класса, который можно будет вызвать однократно. Насколько я понимаю, для этого queryIns_T_BLOCK должно быть известно в обоих этих методах. Еще не написав доп. метод, а только выполнив перенос описания QSqlQuery queryIns_T_BLOCK сюда у меня перестала работать подготовка запроса. prepare стал выдавать ошибку Driver not loaded. Не понимаю, в чем дело. Экземпляры класса QSqlQuery могут быть только локальными переменными? Сообщение отредактировал Steklova Olga - 7.2.2014, 18:45 |
|
|
Litkevich Yuriy |
4.2.2014, 19:50
Сообщение
#2
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
Где бы про это почитать? у Хелен Бори естьА я и не думала, что надо учитывать такие вещи, мне только хотелось оптимизировать работу, чтобы не загружать БД разборкой одинаковых запросов. вот собственно и не думай, оптимизирует сама СУБД, обрати внимание на примеры Qt - QSqlQuery всегда локальная переменная.Применительно к Firebird. Из Qt в Qt-драйвер БД отправляется срока prepare и пачка (массив) аргументов, этот драйвер прям как есть всё отправляет в Firebird, т.е. строка prepare и массив аргументов. Firebird по строке prepare строит план запроса и сохраняет его, затем используя массив аргументов сам "биндит" их в план. В большинстве случаев можно полагать, что сделав с двух разных машин и программ один и тот же prepare Firebird постарается воспользоватся уже подготовленным (с предыдущего события) планом запроса. Firebird кэширует план запроса, в прочем MySQL тоже должен так делать. Собственно времени больше всего уходит именно на построение плана запроса. Лучше будет для оптимизации вообще все эти запросы делать с prepare? Или есть случаи, когда лучше их выполнить сразу, без подготовки, как q.exec(sQuery) ? prepare полезно делать в ситуации, когда ты собираешься несколько наборов данных одинаковым запросом отправлять.П.С. Обрамить всю пачку prepare-bind в транзакцию - существенно увеличить скорость выполнения этой пачки (для любой БД), а для Firebird-а ещё и меньше мусорить, т.к. он версии состояний хранит. П.П.С. Т.к. Firebird версионник, он работает сильно не так как MySql. Недействительным план запроса может стать в других ситуациях. В процессе работы кэш запросов хранит текст запроса SELECT вместе с соответствующим результатом, который посылался клиенту. Вот в Firebird я не помню чтоб результат запроса сколь-нибудь долго кэшировался, для заданной версии, может быть, но версий множество по-этому в общем котле вряд ли. А вот план кэшируется всегда для любого типа запроса |
|
|
Текстовая версия | Сейчас: 29.3.2024, 17:23 |