Russian Qt Forum

Qt => Базы данных => Тема начата: gladsky от Декабрь 15, 2016, 16:38



Название: QSqlTableModel + TableView = медленная работа
Отправлено: gladsky от Декабрь 15, 2016, 16:38
Есть Microsoft SQL server, таблица на 10 колонок, 2000 строк.
Приложение с QSqlTableModel и Tableview работает медленно. Даже если оставить в приложении только отображение одной этой таблицы (взял стандартный пример "cashed table" и заменил там подключение к БД на своё), окошко двигается рывками при масштабировании, прокрутка тоже тормозит.

Если брать данные из БД запросами, хранить их в хеш-таблицах, и выводить через tablewidget - всё идеально. Работает гладко, как будто в экселе таблица открыта. Но количество кода растёт в геометрической прогрессии: нужно прописывать самому делегаты для внешних ключей, логику отображения данных в других виджетах, весь код на запись данных обратно в БД. Если записей будет слишком много, уже придется самому писать логику кеширования и динамической подгрузки данных.

Какие есть способы ускорить работу с QSqlTableModel и Tableview?


Название: Re: QSqlTableModel + TableView = медленная работа
Отправлено: PimenS от Декабрь 15, 2016, 18:36
QSqlTableModel + TableView 50000 строк = никаких тормозов.

Покажите настройки TableView


Название: Re: QSqlTableModel + TableView = медленная работа
Отправлено: Bepec от Декабрь 15, 2016, 22:25
Смотря какие строки. Таблица с более 40 колонками уже начинают подтормаживать :D


Название: Re: QSqlTableModel + TableView = медленная работа
Отправлено: PimenS от Декабрь 16, 2016, 00:13
Смотря какие строки. Таблица с более 40 колонками уже начинают подтормаживать :D

40 не пробовал, ничего не скажу. Но думаю если использовать стандартную модель, да еще представлению сказать resizeColumnsToContents(), то наверное тормоза будут хорошие.


Название: Re: QSqlTableModel + TableView = медленная работа
Отправлено: gladsky от Декабрь 16, 2016, 09:51
Покажите настройки TableView
Всё по умолчанию, я экспериментирую на самом простом примере (программа уже написана под tablewidget, решил по-человечески переписать через модель, пока экспериментирую с производительностью).
Код:
QTableView *view = new QTableView;
view->setModel(model);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addWidget(view);
setLayout(mainLayout);
Сама БД
int;int;date;nvarchar(200);nvarchar(50);nvarchar(50);int;nvarchar(500);nvarchar(20);
Колонки с nvarchar(200) и длиннее скрыты - будут выводится в отдельных виджетах через маппинг.


Название: Re: QSqlTableModel + TableView = медленная работа
Отправлено: Bepec от Декабрь 16, 2016, 09:56
Вы бы лучше весь проект выложили. Возможно у вас ошибка где нить в другом месте, которую вы не видите.


Название: Re: QSqlTableModel + TableView = медленная работа
Отправлено: PimenS от Декабрь 16, 2016, 10:04
Вы бы лучше весь проект выложили. Возможно у вас ошибка где нить в другом месте, которую вы не видите.


Тормоза-то на примере:

Цитировать
взял стандартный пример "cashed table" и заменил там подключение к БД на своё

ЗЫ. Сейчас специально попробовал на такой таблице:

Код:
CREATE TABLE catalogs.ref_spareparts
(
  id uuid NOT NULL, -- Уникальный идентификатор
  code bigint NOT NULL, -- Код
  relname character varying(255) NOT NULL, -- Наименование
  article character varying(50) NOT NULL, -- Артикул
  fullarticle character varying(50) NOT NULL, -- Представление артикула
  producer uuid NOT NULL, -- Производитель
  unit uuid NOT NULL, -- Единица измерения
  crgroup uuid NOT NULL, -- Группа кроссов
  classsize uuid, -- Классификатор размеров
  fullname character varying(250), -- Полное наименование
  partsgroup uuid, -- Товарная группа
  tradegroup uuid, -- Торговая группа
  length integer, -- Длина
  width integer, -- Ширина
  height integer, -- Высота
  weight numeric(15,3), -- Вес
  typelabel uuid, -- Тип этикетки
  printlabel boolean NOT NULL, -- Печатать этикетку
  cunitbar integer NOT NULL, -- Единиц на этикетку
  tsv tsvector,
  CONSTRAINT ref_spareparts_pkey PRIMARY KEY (id),
  CONSTRAINT ref_spareparts_classsize_fkey FOREIGN KEY (classsize)
      REFERENCES catalogs.ref_class_size (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT ref_spareparts_crgroup_fkey FOREIGN KEY (crgroup)
      REFERENCES catalogs.ref_cross_group (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT ref_spareparts_partsgroup_fkey FOREIGN KEY (partsgroup)
      REFERENCES catalogs.ref_partsgroups (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT ref_spareparts_producer_fkey FOREIGN KEY (producer)
      REFERENCES catalogs.ref_producers (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT ref_spareparts_tradegroup_fkey FOREIGN KEY (tradegroup)
      REFERENCES catalogs.ref_tradegroups (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT ref_spareparts_typelabel_fkey FOREIGN KEY (typelabel)
      REFERENCES enumerations.enu_type_label (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT ref_spareparts_unit_fkey FOREIGN KEY (unit)
      REFERENCES catalogs.ref_units (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT ref_spareparts_code_key UNIQUE (code)
)
WITH (
  OIDS=FALSE
);

Строк (сосчитано)   49796  - тормозов не заметил.

Так, что скорее всего или Microsoft SQL server или я не знаю.


Название: Re: QSqlTableModel + TableView = медленная работа
Отправлено: gladsky от Декабрь 19, 2016, 11:28
Судя по всему, QSqlTableModel c TableView не могут нормально работать с сетевыми базами данных, т.к. во-первых запросы к БД идут через создаваемые на лету курсоры вместо обычных селектов, а во-вторых запрос, вставка в таблицу и её отрисовка идут в одном потоке, из-за чего задержка даже в 100 мс между запросом и получением данных приводит к тормозам интерфейса.
Придётся писать свой класс от QAbstractItemModel, чтобы сделать более быструю выгрузку данных и все операции с БД убрать в отдельный поток.