Skip to content

Commit 934c0ee

Browse files
committed
[SqliteWAL]: 重命名类与文件,增加SQLite性能优化配置
- 重构: 将`databasetest`和`databaseutils`统一重命名为`sqlitetest`和`sqliteutils`,提高命名一致性 - 优化: 在`sqliteutils.cc`中添加多组PRAGMA指令优化SQLite性能(WAL模式/内存映射/自动清理等) - 改进: 数据库连接移除时增加ANALYZE/OPTIMIZE等维护操作,减少资源占用 - 安全: 使用`std::call_once`确保测试前删除旧数据库文件,避免数据干扰 - 调试: 添加`printDriverCapabilities()`函数输出SQLite驱动能力信息 - 调整: 将主线程插入次数从1000次降为100次,提升测试效率 - 清理: 移除未使用的`QSqlDriver`头文件和相关调试输出
1 parent 46796cf commit 934c0ee

9 files changed

Lines changed: 145 additions & 86 deletions

File tree

SqliteWAL/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
set(PROJECT_SOURCES databasetest.cc databasetest.hpp databaseutils.cc
2-
databaseutils.hpp main.cc)
1+
set(PROJECT_SOURCES sqlitetest.cc sqlitetest.hpp sqliteutils.cc sqliteutils.hpp
2+
main.cc)
33

44
qt_add_executable(SqliteWAL MANUAL_FINALIZATION ${PROJECT_SOURCES})
55
target_link_libraries(SqliteWAL PRIVATE Qt::Core Qt::Sql)

SqliteWAL/SqliteWAL.pro

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ QT += core sql
55
CONFIG += cmdline
66

77
SOURCES += \
8-
databasetest.cc \
9-
databaseutils.cc \
10-
main.cc
8+
main.cc \
9+
sqlitetest.cc \
10+
sqliteutils.cc
1111

1212
HEADERS += \
13-
databasetest.hpp \
14-
databaseutils.hpp
13+
sqlitetest.hpp \
14+
sqliteutils.hpp
1515

1616
# Default rules for deployment.
1717
qnx: target.path = /tmp/$${TARGET}/bin

SqliteWAL/databasetest.hpp

Lines changed: 0 additions & 17 deletions
This file was deleted.

SqliteWAL/databaseutils.cc

Lines changed: 0 additions & 37 deletions
This file was deleted.

SqliteWAL/main.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "databasetest.hpp"
1+
#include "sqlitetest.hpp"
22

33
#include <QCoreApplication>
44
#include <QSqlDatabase>
@@ -7,8 +7,8 @@
77

88
void insertThread(const QString &brand)
99
{
10-
DataBaseTest test;
11-
for (int i = 0; i < 1000; i++) {
10+
SqliteTest test;
11+
for (int i = 0; i < 100; i++) {
1212
test.insert(brand, i);
1313
}
1414
}
Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
#include "databasetest.hpp"
2-
#include "databaseutils.hpp"
1+
#include "sqlitetest.hpp"
2+
#include "sqliteutils.hpp"
33

44
#include <QDir>
55
#include <QMutex>
6-
#include <QSqlDriver>
76
#include <QSqlError>
87
#include <QSqlQuery>
98
#include <QThread>
109

11-
class DataBaseTest::DataBaseTestPrivate
10+
#include <mutex>
11+
12+
class SqliteTest::SqliteTestPrivate
1213
{
1314
public:
14-
explicit DataBaseTestPrivate(DataBaseTest *q)
15+
explicit SqliteTestPrivate(SqliteTest *q)
1516
: q_ptr(q)
1617
{
1718
dataBaseConnection.dataBasePath = QString("%1/%2").arg(QDir::tempPath()).arg("test.db");
19+
20+
static std::once_flag onceFlag;
21+
std::call_once(onceFlag, [this]() { QFile::remove(this->dataBaseConnection.dataBasePath); });
22+
1823
dataBaseConnection.connectionName = getDatabaseConnectionName();
1924

2025
createTable();
@@ -23,7 +28,7 @@ class DataBaseTest::DataBaseTestPrivate
2328
<< QThread::currentThread();
2429
}
2530

26-
~DataBaseTestPrivate() { removeDatabase(dataBaseConnection.connectionName); }
31+
~SqliteTestPrivate() { removeDatabase(dataBaseConnection); }
2732

2833
bool createTable()
2934
{
@@ -41,12 +46,6 @@ class DataBaseTest::DataBaseTestPrivate
4146
auto db = getDatabase(dataBaseConnection);
4247
CHECK_DATABASE_VALIDITY(db)
4348

44-
auto *driver = db.driver();
45-
qInfo() << "Support Transactions: " << driver->hasFeature(QSqlDriver::Transactions)
46-
<< "Support LastInsertId: " << driver->hasFeature(QSqlDriver::LastInsertId)
47-
<< "Support BatchOperations: " << driver->hasFeature(QSqlDriver::BatchOperations)
48-
<< "Support SimpleLocking: " << driver->hasFeature(QSqlDriver::SimpleLocking);
49-
5049
if (db.tables().contains(tableName)) {
5150
return true;
5251
}
@@ -59,24 +58,24 @@ class DataBaseTest::DataBaseTestPrivate
5958
return true;
6059
}
6160

62-
DataBaseTest *q_ptr;
61+
SqliteTest *q_ptr;
6362

64-
DataBaseConnection dataBaseConnection;
63+
SqliteConnection dataBaseConnection;
6564
const QString tableName = "phone";
6665

6766
static QMutex mutex;
6867
};
6968

70-
QMutex DataBaseTest::DataBaseTestPrivate::mutex;
69+
QMutex SqliteTest::SqliteTestPrivate::mutex;
7170

72-
DataBaseTest::DataBaseTest(QObject *parent)
71+
SqliteTest::SqliteTest(QObject *parent)
7372
: QObject{parent}
74-
, d_ptr(new DataBaseTestPrivate(this))
73+
, d_ptr(new SqliteTestPrivate(this))
7574
{}
7675

77-
DataBaseTest::~DataBaseTest() {}
76+
SqliteTest::~SqliteTest() {}
7877

79-
bool DataBaseTest::insert(const QString &brand, int num)
78+
bool SqliteTest::insert(const QString &brand, int num)
8079
{
8180
QMutexLocker locker(&d_ptr->mutex);
8281
auto db = getDatabase(d_ptr->dataBaseConnection);

SqliteWAL/sqlitetest.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include <QObject>
4+
5+
class SqliteTest : public QObject
6+
{
7+
Q_OBJECT
8+
public:
9+
explicit SqliteTest(QObject *parent = nullptr);
10+
~SqliteTest();
11+
12+
bool insert(const QString &brand, int num);
13+
14+
private:
15+
class SqliteTestPrivate;
16+
QScopedPointer<SqliteTestPrivate> d_ptr;
17+
};

SqliteWAL/sqliteutils.cc

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include "sqliteutils.hpp"
2+
3+
#include <QFile>
4+
#include <QSqlDriver>
5+
#include <QSqlError>
6+
#include <QSqlQuery>
7+
8+
#include <mutex>
9+
10+
void printDriverCapabilities(QSqlDriver *driver)
11+
{
12+
static std::once_flag once;
13+
std::call_once(once, [driver] {
14+
qInfo().noquote() << "SQLite driver capabilities:\n"
15+
<< " Transactions :" << driver->hasFeature(QSqlDriver::Transactions)
16+
<< '\n'
17+
<< " LastInsertId :" << driver->hasFeature(QSqlDriver::LastInsertId)
18+
<< '\n'
19+
<< " BatchOperations :"
20+
<< driver->hasFeature(QSqlDriver::BatchOperations) << '\n'
21+
<< " SimpleLocking :" << driver->hasFeature(QSqlDriver::SimpleLocking);
22+
});
23+
}
24+
25+
void queryOptions(QSqlQuery &query, const QStringList &options)
26+
{
27+
for (const auto &option : std::as_const(options)) {
28+
if (!query.exec(option)) {
29+
qWarning() << "Failed to execute " << option << ":" << query.lastError().text();
30+
}
31+
}
32+
}
33+
34+
QSqlDatabase getDatabase(const SqliteConnection &dataBaseConnection)
35+
{
36+
auto db = QSqlDatabase::database(dataBaseConnection.connectionName);
37+
if (!db.isValid()) {
38+
db = QSqlDatabase::addDatabase("QSQLITE", dataBaseConnection.connectionName);
39+
db.setDatabaseName(dataBaseConnection.dataBasePath);
40+
}
41+
42+
if (!db.isOpen()) {
43+
if (!db.open()) {
44+
QFile(dataBaseConnection.dataBasePath).remove();
45+
db.open();
46+
}
47+
static const QStringList options = {
48+
"PRAGMA journal_mode = WAL;", // 启用WAL模式
49+
"PRAGMA optimize = 0x10002;", // 启用自动索引和查询优化
50+
"PRAGMA auto_vacuum = INCREMENTAL;", // 启用自动VACUUM
51+
"PRAGMA default_temp_store = MEMORY;", // 启用内存临时表
52+
"PRAGMA temp_store = MEMORY;", // 启用内存临时表
53+
"PRAGMA page_size = 4096;", // 设置页面大小
54+
"PRAGMA cache_size = -32768;", // 设置缓存大小,单位为KB
55+
"PRAGMA wal_autocheckpoint = 1000;", // 设置WAL自动检查点间隔
56+
"PRAGMA mmap_size = 268435456;", // 启用内存映射,最大256MB
57+
"PRAGMA cache_spill = false;" // 禁用缓存溢出
58+
// "PRAGMA synchronous = NORMAL;", // 性能提升,耐久性略降
59+
// "PRAGMA locking_mode = EXCLUSIVE;", // 独占锁,适合单进程
60+
// "PRAGMA foreign_keys = ON;", // 启用外键约束
61+
};
62+
QSqlQuery query(db);
63+
queryOptions(query, options);
64+
65+
printDriverCapabilities(db.driver());
66+
}
67+
68+
return db;
69+
}
70+
71+
void removeDatabase(const SqliteConnection &dataBaseConnection)
72+
{
73+
auto connectionName = dataBaseConnection.connectionName;
74+
if (!QSqlDatabase::contains(connectionName)) {
75+
return;
76+
}
77+
static const QStringList options = {
78+
"ANALYZE;", // 分析数据库
79+
"PRAGMA optimize;", // 优化数据库
80+
"PRAGMA incremental_vacuum;", // 增量VACUUM
81+
"PRAGMA journal_size_limit = 8388608;", // 限制日志文件大小为8MB
82+
"PRAGMA wal_checkpoint(TRUNCATE);", // 检查点并截断WAL文件
83+
"PRAGMA shrink_memory;", // 释放内存
84+
};
85+
{
86+
QSqlQuery query(getDatabase(dataBaseConnection));
87+
queryOptions(query, options);
88+
}
89+
90+
QSqlDatabase::removeDatabase(connectionName);
91+
}
92+
93+
QString getDatabaseConnectionName()
94+
{
95+
static std::atomic_llong id = 1;
96+
return QString("connection_%1").arg(id.fetch_add(1));
97+
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
#include <QSqlDatabase>
44

5-
struct DataBaseConnection
5+
struct SqliteConnection
66
{
77
QString connectionName;
88
QString dataBasePath;
99
};
1010

11-
QSqlDatabase getDatabase(const DataBaseConnection &dataBaseConnection);
11+
QSqlDatabase getDatabase(const SqliteConnection &dataBaseConnection);
1212

13-
void removeDatabase(const QString &connectionName);
13+
void removeDatabase(const SqliteConnection &dataBaseConnection);
1414

1515
QString getDatabaseConnectionName();
1616

0 commit comments

Comments
 (0)