0
点赞
收藏
分享

微信扫一扫

Qt 使用SQLite的性能优化的亿点点记录


Qt 使用SQLite的性能优化的亿点点记录_事务模式

Qt 使用SQLite的性能优化的亿点点记录

文章目录

  • ​​Qt 使用SQLite的性能优化的亿点点记录​​
  • ​​摘要​​
  • ​​第一版本​​
  • ​​出现问题​​
  • ​​第二版本​​
  • ​​第三版本​​


关键字:

​事务模式​​、

​执行准备​​、

​Qt​​、

​SQL​​、

​SQLite​

摘要

今天又是美好的一天,因为要发工资了,哈哈哈;但是,活还得干。

基本需求呢,就是我会实时读取数据,玩了把它写入到数据库中,本来这个时间序列数据应该整个正式的东西来存储,但是呢,我不会,正好手头就有现成的SQLite数据库可以使用,所以就用了。下面是各种记录的坑。

第一版本

这个版本呢,没有做任何优化处理,就是普通的数据库插入。

代码非常简单,就是一句话,如下

sql_query.exec(QString("insert into %1(Date0,Data1,Data2) values ('%2', '%3', '%4')").arg(gPatientName).arg(0).arg(jsonData1).arg(jsonData2));

出现问题

这里要不就是啥事都得实践了,这么写在语法上没有任何问题,但是最后结果却不是自己想要的。我理论上每秒钟应该会插入 8000次数据,但是在我辛苦跑了两小时(为啥是两小时,因为我想摸鱼,哈哈哈),发现数据并没有达到我的需求。所以在这里就开始找问题,就有了下面这个网址,要么所心情好,啥都好了,没想到这么快就有了解决办法。


每一个人创作都不容易,这里还是推荐大家去看看作者写的,非常牛逼。

优化方法

无优化

关闭写同步

开启事务

执行准备

内存模式

每秒插入

13条

1321条

5万条

213万条

215万条

所以就会出现了第二个版本

第二版本

开启事务模式,这个就够我用了。其实还可以使用执行准备模式,但是要加好多条代码,所以就放弃了,如果需求,就可以在搞上执行准备。

void Turing_USB_DataAnalysis::slot_insertDB()
{
if(sqlCount == 0)
sql_query.exec("BEGIN TRANSACTION;"); // 开启数据库事物
sql_query.exec(QString("insert into %1(Date0,Data1,Data2) values ('%2', '%3', '%4')").arg(gPatientName).arg(0).arg(jsonData1).arg(jsonData2));
sqlCount++;
if(sqlCount == 2000)
{
sql_query.exec("END TRANSACTION;"); // 真正的更新数据到数据库
sqlCount = 0;
}
}

第三版本

这里就可以开启执行准备了,执行准备Qt写实帮助我们实现了的,作者用的是直接调用的方式,我们还是可以用Qt的QSqlQuery来实现。示例如下,这里就直接搬运官方文档了,由于暂时我用不到,所以就不考虑实现了。

bool QSqlQuery::prepare(const QString &query)
Prepares the SQL query query for execution. Returns true if the query is prepared successfully; otherwise returns false.
The query may contain placeholders for binding values. Both Oracle style colon-name (e.g., :surname), and ODBC style (?) placeholders are supported; but they cannot be mixed in the same query. See the Detailed Description for examples.
Portability notes: Some databases choose to delay preparing a query until it is executed the first time. In this case, preparing a syntactically wrong query succeeds, but every consecutive exec() will fail. When the database does not support named placeholders directly, the placeholder can only contain characters in the range [a-zA-Z0-9_].
For SQLite, the query string can contain only one statement at a time. If more than one statement is given, the function returns false.
Example:
QSqlQuery query;
query.prepare(“INSERT INTO person (id, forename, surname) "
“VALUES (:id, :forename, :surname)”);
query.bindValue(”:id", 1001);
query.bindValue(“:forename”, “Bart”);
query.bindValue(“:surname”, “Simpson”);
query.exec();
See also exec(), bindValue(), and addBindValue().



举报

相关推荐

0 条评论