Qt - QTreeView и SQL - Советы по производительности - PullRequest
3 голосов
/ 02 февраля 2011

У меня есть приложение, в котором я хочу показать результаты SQL-запроса в иерархической структуре. У меня есть кое-что, что основано на этом примере .

Основная часть моего кода, где создаются узлы дерева, выглядит следующим образом:

void TreeModel::setupModelData(TreeItem *parent)
{
  QList<TreeItem*> parents;
  QList<int> indentations;
  parents << parent;     
  QList<QVariant> columnData;

  QVector<QString> vecFileNames = getFileNames();
  QVector<QString> vecTableNames = getTableNames();

  for(int i = 0; i < vecFileNames.size(); i++)
  {
    columnData.clear();
    columnData << vecFileNames[i];
    parents.last()->appendChild(new TreeItem(columnData, parents.last()));

    int childCount = parents.last()->childCount() - 1;
    parents << parents.last()->child(childCount);    //add the current parent's last child as a parent

    for(int j = 0; j < vecTableNames.size(); j++)
    {
      columnData.clear();
      columnData << vecTableNames[j];
      parents.last()->appendChild(new TreeItem(columnData, parents.last()));

      QVector<QString> vecTableValues = getTableValues(&vecTableNames[j]);
      int childCount = parents.last()->childCount() - 1;
      parents << parents.last()->child(childCount);         //add the current parent's last child as a parent

      for(int k = 0; k < vecTableValues.size(); k++)
      {
        columnData.clear();
        columnData << vecTableValues[j];
        parents.last()->appendChild(new TreeItem(columnData, parents.last()));
      }

    }
    parents.pop_back();
  }

}

QVector<QString> TreeModel::getFileNames()
{
  db.open();

  QVector<QString> vecFileNames;
  QSqlQuery query(db);
  QString strQuery = "SELECT PK_fileName FROM fileproperties";
  query.prepare(strQuery);

  if(query.exec() == true)
  {
    while(query.next())
    {
      vecFileNames.push_back(query.value(0).toString());
    }
  }

  db.close();
  return vecFileNames;
}

Тем не менее, он невероятно медленно извлекает данные из 2000 запросов. Кто-нибудь может предложить другой подход к тому, который я сейчас использую?

Ответы [ 3 ]

1 голос
/ 02 февраля 2011

Вы должны реализовать функцию hasChildren () и использовать ленивая совокупность данных модели .В основном вам следует прочитать эту статью и документацию класса QAbstractItemModel (особенно функции canFetchMore () ).

0 голосов
/ 15 февраля 2011

Я бы предположил, что производительность страдает, вставляя 2000 записей по отдельности, вызывая 2000 обновлений представлений, возможно 2000 сортировок и т. Д. Вы должны предоставить способ добавления данных в вашу модель, который принимает «партии» элементов и только сигнализирует об изменениях один раз ...

0 голосов
/ 03 февраля 2011

Для серверов MS SQL я всегда использую QSqlQuery :: setForward (true) для ускорения запросов до 10 раз.

Этот режим «пересылки» просто отключает кэши строк и заставляет драйвер sql запрашивать все результаты в виде одного жирного ответа, а не получать результаты запроса в виде нескольких частей (одна или несколько строк).

Я обнаружил проблему с MS SQL Server 2005 + 2008 с более чем 10 миллионами записей, где я искал только 200-400 записей для особого дня, чтобы отобразить их внутри QTableView с помощью QSqlTableModel.

С включенным режимом пересылки время моего запроса увеличилось с 10 секунд до 200-300 миллисекунд - для базы данных с более чем 10 миллионами записей!

Пример:

QSqlQuery query(database);
query.setForwardOnly(m_bForwardOnly);

query.exec(statement);
if ( query.lastError().isValid() || database.lastError().isValid() ) {
   ...evaluate the results...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...