1
0
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:
Anthony Bilinski 2019-10-11 17:15:33 -07:00
parent af19c0d73b
commit edd72906fb
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
2 changed files with 48 additions and 3 deletions

View File

@ -26,7 +26,7 @@
#include "db/rawdatabase.h" #include "db/rawdatabase.h"
namespace { namespace {
static constexpr int SCHEMA_VERSION = 3; static constexpr int SCHEMA_VERSION = 4;
bool createCurrentSchema(RawDatabase& db) bool createCurrentSchema(RawDatabase& db)
{ {
@ -63,6 +63,9 @@ bool createCurrentSchema(RawDatabase& db)
"file_state INTEGER NOT NULL);" "file_state INTEGER NOT NULL);"
"CREATE TABLE faux_offline_pending (id INTEGER PRIMARY KEY);" "CREATE TABLE faux_offline_pending (id INTEGER PRIMARY KEY);"
"CREATE TABLE broken_messages (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)); queries += RawDatabase::Query(QStringLiteral("PRAGMA user_version = %1;").arg(SCHEMA_VERSION));
return db.execNow(queries); return db.execNow(queries);
} }
@ -178,6 +181,18 @@ bool dbSchema2to3(RawDatabase& db)
return db.execNow(upgradeQueries); 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 * @brief Upgrade the db schema
* @note On future alterations of the database all you have to do is bump the SCHEMA_VERSION * @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; return;
} }
qDebug() << "Database upgraded incrementally to schema version 3"; 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. // etc.
default: default:
qInfo() << "Database upgrade finished (databaseSchemaVersion" << databaseSchemaVersion qInfo() << "Database upgrade finished (databaseSchemaVersion" << databaseSchemaVersion

View File

@ -37,6 +37,7 @@ private slots:
void test0to1(); void test0to1();
void test1to2(); void test1to2();
void test2to3(); void test2to3();
void test3to4();
void cleanupTestCase(); void cleanupTestCase();
private: private:
bool initSucess{false}; bool initSucess{false};
@ -50,9 +51,12 @@ const QString testFileList[] = {
"testIsNewDbFalse.db", "testIsNewDbFalse.db",
"test0to1.db", "test0to1.db",
"test1to2.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 { const QMap<QString, QString> schema0 {
{"aliases", "CREATE TABLE aliases (id INTEGER PRIMARY KEY, owner INTEGER, display_name BLOB NOT NULL, UNIQUE(owner, display_name))"}, {"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)"}, {"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. // move stuck 0-length action messages to the existing "broken_messages" table. Not a real schema upgrade.
const auto schema3 = schema2; 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() void TestDbSchema::initTestCase()
{ {
for (const auto& path : testFileList) { for (const auto& path : testFileList) {
@ -132,7 +147,7 @@ void TestDbSchema::testCreation()
QVector<RawDatabase::Query> queries; QVector<RawDatabase::Query> queries;
auto db = std::shared_ptr<RawDatabase>{new RawDatabase{"testCreation.db", {}, {}}}; auto db = std::shared_ptr<RawDatabase>{new RawDatabase{"testCreation.db", {}, {}}};
QVERIFY(createCurrentSchema(*db)); QVERIFY(createCurrentSchema(*db));
verifyDb(db, schema3); verifyDb(db, schema4);
} }
void TestDbSchema::testIsNewDb() void TestDbSchema::testIsNewDb()
@ -314,5 +329,13 @@ void TestDbSchema::test2to3()
verifyDb(db, schema3); 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) QTEST_GUILESS_MAIN(TestDbSchema)
#include "dbschema_test.moc" #include "dbschema_test.moc"