2

Ubuntu14.04 64bitでQSqlDatabasesqlite3を使用するQt5.4の場合:

transaction()まず、データベースを開いて呼び出します。

次に、54 個の個別の挿入クエリを作成します。それぞれが準備され、実行後に削除されます。

最後に を呼び出しますcommit()

すべての呼び出しはエラーなしで完了しますが、それでも実行時間は恐ろしいものです (54 回の些細な挿入で合計約 500 ミリ秒)。

私のコンピューターは比較的新しく、パフォーマンスのために SSD ディスクをストライプ化しています。Sqliteman を使用して sqlite ファイルにアクセスすると、非常に高速です。

何が起こっているのですか?

ここに挿入があります:

void BottleRigStorage::upsertTag(Tag &tag){
    //ScopedTimer st("query time for tag");
    if(open()){

            QSqlQuery query(db);
            query.prepare("INSERT OR REPLACE INTO tags ("
                          "  id"
                          ", batchID"
                          ", retries"
                          ", good"
                          ", status"
                          ", color"
                          ", firstCheckTimestamp"
                          ", createdTimestamp"
                          ", modifiedTimestamp"
                          ", fulfilledTimestamp"
                          ") VALUES ("
                          "  :id"
                          ", :batchID"
                          ", :retries"
                          ", :good"
                          ", :status"
                          ", :color"
                          ", :firstCheckTimestamp"
                          ", :createdTimestamp"
                          ", :modifiedTimestamp"
                          ", :fulfilledTimestamp"
                          ");");
            query.bindValue(":id", tag.id);//8 chars
            query.bindValue(":batchID", tag.batchID);//8 chars
            query.bindValue(":retries", tag.retries);//int
            query.bindValue(":good",tag.good?1:0);//bool
            query.bindValue(":status", tag.status);//6 chars
            query.bindValue(":color", tag.color);//7 chars
            query.bindValue(":firstCheckTimestamp", tag.firstCheckTimestamp); //long
            query.bindValue(":createdTimestamp", tag.createdTimestamp);//long
            query.bindValue(":modifiedTimestamp", tag.modifiedTimestamp);//long
            query.bindValue(":fulfilledTimestamp", tag.fulfilledTimestamp);//long

            if (query.exec()) {
                //qDebug() << "Successfully updated tag database after "<<st.getIntervalCompleteString();
            }
            else {
                qWarning() << "ERROR: could not upsert tag with id " << tag.id<< ". Reason: "<< query.lastError();
            }
            query.finish();
        }

    else {
        qWarning() << "ERROR: DB not open for upsert tag sqlite3";
    }
}

更新: そして、要求された open() は次のとおりです。

bool BottleRigStorage::open(){
    if(!db.isOpen()){
        if(!db.open()){
            qWarning() << "ERROR: could not open database. Reason: "<<db.lastError();
        }
    }
    return db.isOpen();
}
4

2 に答える 2

5
  1. prepare は 1 回だけ使用してください。QSqlQuery の作成後、コードは毎回クエリを準備しています。関数の外で準備して QSqlQuery を作成する必要があり、関数内で値バインディングと SQL クエリ exec を使用するだけです。

    void BottleRigStorage::upsertTag(Tag &tag){
    //ScopedTimer st("query time for tag");
    if(open()){
            query.bindValue(":id", tag.id);//8 chars
            query.bindValue(":batchID", tag.batchID);//8 chars
            query.bindValue(":retries", tag.retries);//int
            query.bindValue(":good",tag.good?1:0);//bool
            query.bindValue(":status", tag.status);//6 chars
            query.bindValue(":color", tag.color);//7 chars
            query.bindValue(":firstCheckTimestamp", tag.firstCheckTimestamp); //long
            query.bindValue(":createdTimestamp", tag.createdTimestamp);//long
            query.bindValue(":modifiedTimestamp", tag.modifiedTimestamp);//long
            query.bindValue(":fulfilledTimestamp", tag.fulfilledTimestamp);//long
    
            if (query.exec()) {
                //qDebug() << "Successfully updated tag database after "<<st.getIntervalCompleteString();
            }
            else {
                qWarning() << "ERROR: could not upsert tag with id " << tag.id<< ". Reason: "<< query.lastError();
            }
            query.finish();
        }
    
    else {
        qWarning() << "ERROR: DB not open for upsert tag sqlite3";
    }
    

    }

    この場合のクエリ オブジェクトはプライベート メンバーであり、たとえばデータベースの初期化後に作成できます。

  2. プラグマを介して sqlite データベースをチューニングできます。たとえば、次のコードはクエリの実行を増やします。

    m_pDatabase->exec("PRAGMA 同期 = OFF"); m_pDatabase->exec("PRAGMA journal_mode = MEMORY");

    詳細については、こちらをご覧ください

于 2015-07-03T13:39:13.543 に答える