mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
perf(history): enable sql index on chat_id in history table
This makes every query with a "WHERE history.chat_id" clause quicker, improving history load time by 50% on my profile. Related to #5812
This commit is contained in:
parent
af19c0d73b
commit
edd72906fb
|
@ -26,7 +26,7 @@
|
|||
#include "db/rawdatabase.h"
|
||||
|
||||
namespace {
|
||||
static constexpr int SCHEMA_VERSION = 3;
|
||||
static constexpr int SCHEMA_VERSION = 4;
|
||||
|
||||
bool createCurrentSchema(RawDatabase& db)
|
||||
{
|
||||
|
@ -63,6 +63,9 @@ bool createCurrentSchema(RawDatabase& db)
|
|||
"file_state INTEGER NOT NULL);"
|
||||
"CREATE TABLE faux_offline_pending (id INTEGER PRIMARY KEY);"
|
||||
"CREATE TABLE broken_messages (id INTEGER PRIMARY KEY);"));
|
||||
// sqlite doesn't support including the index as part of the CREATE TABLE statement, so add a second query
|
||||
queries += RawDatabase::Query(
|
||||
"CREATE INDEX chat_id_idx on history (chat_id);");
|
||||
queries += RawDatabase::Query(QStringLiteral("PRAGMA user_version = %1;").arg(SCHEMA_VERSION));
|
||||
return db.execNow(queries);
|
||||
}
|
||||
|
@ -178,6 +181,18 @@ bool dbSchema2to3(RawDatabase& db)
|
|||
return db.execNow(upgradeQueries);
|
||||
}
|
||||
|
||||
bool dbSchema3to4(RawDatabase& db)
|
||||
{
|
||||
QVector<RawDatabase::Query> upgradeQueries;
|
||||
upgradeQueries += RawDatabase::Query{QString(
|
||||
"CREATE INDEX chat_id_idx on history (chat_id);")};
|
||||
|
||||
upgradeQueries += RawDatabase::Query(QStringLiteral("PRAGMA user_version = 4;"));
|
||||
|
||||
return db.execNow(upgradeQueries);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Upgrade the db schema
|
||||
* @note On future alterations of the database all you have to do is bump the SCHEMA_VERSION
|
||||
|
@ -252,6 +267,13 @@ void dbSchemaUpgrade(std::shared_ptr<RawDatabase>& db)
|
|||
return;
|
||||
}
|
||||
qDebug() << "Database upgraded incrementally to schema version 3";
|
||||
case 3:
|
||||
if (!dbSchema3to4(*db)) {
|
||||
qCritical() << "Failed to upgrade db to schema version 4, aborting";
|
||||
db.reset();
|
||||
return;
|
||||
}
|
||||
qDebug() << "Database upgraded incrementally to schema version 4";
|
||||
// etc.
|
||||
default:
|
||||
qInfo() << "Database upgrade finished (databaseSchemaVersion" << databaseSchemaVersion
|
||||
|
|
|
@ -37,6 +37,7 @@ private slots:
|
|||
void test0to1();
|
||||
void test1to2();
|
||||
void test2to3();
|
||||
void test3to4();
|
||||
void cleanupTestCase();
|
||||
private:
|
||||
bool initSucess{false};
|
||||
|
@ -50,9 +51,12 @@ const QString testFileList[] = {
|
|||
"testIsNewDbFalse.db",
|
||||
"test0to1.db",
|
||||
"test1to2.db",
|
||||
"test2to3.db"
|
||||
"test2to3.db",
|
||||
"test3to4.db"
|
||||
};
|
||||
|
||||
// db schemas can be select with "SELECT name, sql FROM sqlite_master;" on the database.
|
||||
|
||||
const QMap<QString, QString> schema0 {
|
||||
{"aliases", "CREATE TABLE aliases (id INTEGER PRIMARY KEY, owner INTEGER, display_name BLOB NOT NULL, UNIQUE(owner, display_name))"},
|
||||
{"faux_offline_pending", "CREATE TABLE faux_offline_pending (id INTEGER PRIMARY KEY)"},
|
||||
|
@ -82,6 +86,17 @@ const QMap<QString, QString> schema2 {
|
|||
// move stuck 0-length action messages to the existing "broken_messages" table. Not a real schema upgrade.
|
||||
const auto schema3 = schema2;
|
||||
|
||||
// create index in history table on chat_id to improve query speed. Not a real schema upgrade.
|
||||
const QMap<QString, QString> schema4 {
|
||||
{"aliases", "CREATE TABLE aliases (id INTEGER PRIMARY KEY, owner INTEGER, display_name BLOB NOT NULL, UNIQUE(owner, display_name))"},
|
||||
{"faux_offline_pending", "CREATE TABLE faux_offline_pending (id INTEGER PRIMARY KEY)"},
|
||||
{"file_transfers", "CREATE TABLE file_transfers (id INTEGER PRIMARY KEY, chat_id INTEGER NOT NULL, file_restart_id BLOB NOT NULL, file_name BLOB NOT NULL, file_path BLOB NOT NULL, file_hash BLOB NOT NULL, file_size INTEGER NOT NULL, direction INTEGER NOT NULL, file_state INTEGER NOT NULL)"},
|
||||
{"history", "CREATE TABLE history (id INTEGER PRIMARY KEY, timestamp INTEGER NOT NULL, chat_id INTEGER NOT NULL, sender_alias INTEGER NOT NULL, message BLOB NOT NULL, file_id INTEGER)"},
|
||||
{"peers", "CREATE TABLE peers (id INTEGER PRIMARY KEY, public_key TEXT NOT NULL UNIQUE)"},
|
||||
{"broken_messages", "CREATE TABLE broken_messages (id INTEGER PRIMARY KEY)"},
|
||||
{"chat_id_idx", "CREATE INDEX chat_id_idx on history (chat_id)"}
|
||||
};
|
||||
|
||||
void TestDbSchema::initTestCase()
|
||||
{
|
||||
for (const auto& path : testFileList) {
|
||||
|
@ -132,7 +147,7 @@ void TestDbSchema::testCreation()
|
|||
QVector<RawDatabase::Query> queries;
|
||||
auto db = std::shared_ptr<RawDatabase>{new RawDatabase{"testCreation.db", {}, {}}};
|
||||
QVERIFY(createCurrentSchema(*db));
|
||||
verifyDb(db, schema3);
|
||||
verifyDb(db, schema4);
|
||||
}
|
||||
|
||||
void TestDbSchema::testIsNewDb()
|
||||
|
@ -314,5 +329,13 @@ void TestDbSchema::test2to3()
|
|||
verifyDb(db, schema3);
|
||||
}
|
||||
|
||||
void TestDbSchema::test3to4()
|
||||
{
|
||||
auto db = std::shared_ptr<RawDatabase>{new RawDatabase{"test3to4.db", {}, {}}};
|
||||
createSchemaAtVersion(db, schema3);
|
||||
QVERIFY(dbSchema3to4(*db));
|
||||
verifyDb(db, schema4);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestDbSchema)
|
||||
#include "dbschema_test.moc"
|
||||
|
|
Loading…
Reference in New Issue
Block a user