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"
|
#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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user