之前做个爬虫,想把数据写入本地数据库,发现数据库的写入速度每条只有10次左右,一直没有找到好的方法提升他。在一次偶然的机会看到了关于sqlite的一些设置,才知道可以通过设置提升的。其实原理就是不让数据库的每次提交写入磁盘,而做一个缓存,每隔一定时间进行提交
不废话了,直接上代码
#include <QCoreApplication>
#include <QTextCodec>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QTime>
#include <QSqlError>
#include <QtDebug>
#include <QSqlDriver>
#include <QSqlRecord>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("easybook-3313b0"); //设置数据库主机名
db.setDatabaseName("qtDB.db"); //设置数据库名
db.setUserName("zhouhejun"); //设置数据库用户名
db.setPassword("123456"); //设置数据库密码
db.open(); //打开连接
//创建数据库表
QSqlQuery query;
bool success=query.exec("create table automobil(id int primary key,attribute varchar,type varchar,kind varchar,nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
if(success)
qDebug()<<QObject::tr("数据库表创建成功!\n");
else
qDebug()<<QObject::tr("数据库表创建失败!\n");
// query.exec("PRAGMA synchronous=OFF;");
// query.exec("PRAGMA Journal_Mode=WAL;");
// query.exec("PRAGMA Cache_Size=5000;");
//查询
query.exec("select * from automobil");
QSqlRecord rec = query.record();
qDebug() << QObject::tr("automobil表字段数:" )<< rec.count();
//插入记录
QTime t;
t.start();
query.prepare("insert into automobil values(?,?,?,?,?,?,?,?,?,?)");
long records=5000;
for(int i=0;i<records;i++)
{
query.bindValue(0,i);
query.bindValue(1,"四轮");
query.bindValue(2,"轿车");
query.bindValue(3,"富康");
query.bindValue(4,rand()%100);
query.bindValue(5,rand()%10000);
query.bindValue(6,rand()%300);
query.bindValue(7,rand()%200000);
query.bindValue(8,rand()%52);
query.bindValue(9,rand()%100);
success=query.exec();
if(!success)
{
QSqlError lastError=query.lastError();
qDebug()<<lastError.driverText()<<QString(QObject::tr("插入失败"));
}
}
qDebug()<<QObject::tr("插入 %1 条记录,耗时:%2 ms").arg(records).arg(t.elapsed());
return 0;
//return a.exec();
}
来一个,没有 进行关闭同步的效果图
再来一个关闭同步的效果图
其实关键就是这几行代码
query.exec("PRAGMA synchronous=OFF;");
query.exec("PRAGMA Journal_Mode=WAL;");
query.exec("PRAGMA Cache_Size=5000;");
如果我们换成100000条数据呢
其实我们还有更快的方案,看下图
其实就是用事务在关闭同步的基础上加上事务
#include <QCoreApplication>
#include <QTextCodec>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QTime>
#include <QSqlError>
#include <QtDebug>
#include <QSqlDriver>
#include <QSqlRecord>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("easybook-3313b0"); //设置数据库主机名
db.setDatabaseName("qtDB.db"); //设置数据库名
db.setUserName("zhouhejun"); //设置数据库用户名
db.setPassword("123456"); //设置数据库密码
db.open(); //打开连接
//创建数据库表
QSqlQuery query;
bool success=query.exec("create table automobil(id int primary key,attribute varchar,type varchar,kind varchar,nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
if(success)
qDebug()<<QObject::tr("数据库表创建成功!\n");
else
qDebug()<<QObject::tr("数据库表创建失败!\n");
query.exec("PRAGMA synchronous=OFF;");
query.exec("PRAGMA Journal_Mode=WAL;");
query.exec("PRAGMA Cache_Size=5000;");
//查询
query.exec("select * from automobil");
QSqlRecord rec = query.record();
qDebug() << QObject::tr("automobil表字段数:" )<< rec.count();
//插入记录
QTime t;
t.start();
db.transaction(); //开始启动事务
query.prepare("insert into automobil values(?,?,?,?,?,?,?,?,?,?)");
long records=100000;
for(int i=0;i<records;i++)
{
query.bindValue(0,i);
query.bindValue(1,"四轮");
query.bindValue(2,"轿车");
query.bindValue(3,"富康");
query.bindValue(4,rand()%100);
query.bindValue(5,rand()%10000);
query.bindValue(6,rand()%300);
query.bindValue(7,rand()%200000);
query.bindValue(8,rand()%52);
query.bindValue(9,rand()%100);
query.execBatch();
}
db.commit();
qDebug()<<QObject::tr("插入 %1 条记录,耗时:%2 ms").arg(records).arg(t.elapsed());
return 0;
//return a.exec();
}