我看到人们最近在很多帖子中试图读取这样的文件.
码
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
char *path = argc > 1 ? argv[1] : "input.txt";
FILE *fp = fopen(path, "r");
if( fp == NULL ) {
perror(path);
return EXIT_FAILURE;
}
while( !feof(fp) ) { /* THIS IS WRONG */
/* Read and process data from file… */
}
if( fclose(fp) == 0 ) {
return EXIT_SUCCESS;
} else {
perror(path);
return EXIT_FAILURE;
}
}
Run Code Online (Sandbox Code Playgroud)
这个__CODE__
循环有什么问题?
在MySQL中,您可以插入多行,如下所示:
INSERT INTO 'tablename' ('column1', 'column2') VALUES
('data1', 'data2'),
('data1', 'data2'),
('data1', 'data2'),
('data1', 'data2');
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试做这样的事情时,我收到了一个错误.是否可以在SQLite数据库中一次插入多行?这样做的语法是什么?
我知道sqlite对于非常大的数据库文件表现不佳,即使它们受支持(曾经在sqlite网站上发表评论,说明如果你需要的文件大小超过1GB,你可能要考虑使用企业rdbms.再找不到它,可能与旧版本的sqlite有关.
但是,出于我的目的,我想在考虑其他解决方案之前了解它到底有多糟糕.
我说的是数千兆字节的sqlite数据文件,从2GB开始.有人对此有经验吗?任何提示/想法?
仅使用ANSI C,有没有办法以毫秒或更多精度测量时间?我正在浏览time.h但我只发现了第二个精确功能.
为什么这个简单的测试用例使用SQLAlchemy插入100,000行比直接使用sqlite3驱动程序慢25倍?我在实际应用程序中看到了类似的减速.难道我做错了什么?
#!/usr/bin/env python
# Why is SQLAlchemy with SQLite so slow?
# Output from this program:
# SqlAlchemy: Total time for 100000 records 10.74 secs
# sqlite3: Total time for 100000 records 0.40 secs
import time
import sqlite3
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
Base = declarative_base()
DBSession = scoped_session(sessionmaker())
class Customer(Base):
__tablename__ = "customer"
id = Column(Integer, primary_key=True)
name = Column(String(255))
def init_sqlalchemy(dbname = 'sqlite:///sqlalchemy.db'):
engine = create_engine(dbname, echo=False) …
Run Code Online (Sandbox Code Playgroud) 众所周知,SQLite 需要经过精细调整,以实现大约50k插入/秒的插入速度.这里有很多关于缓慢插入速度和大量建议和基准的问题.
还有声称SQLite可以处理大量数据,50 GB以上的报告不会导致正确设置出现任何问题.
我已经按照这里和其他地方的建议来实现这些速度,我很高兴35k-45k插入/秒.我遇到的问题是所有的基准测试只能显示<1m记录的快速插入速度.我所看到的是插入速度似乎与表格大小成反比.
我的用例要求[x_id, y_id, z_id]
在链接表中存储500米到1b元组()几年(1米行/天).值均为介于1和2,000,000之间的整数ID.有一个索引z_id
.
前10米行的性能非常好,约35k插入/秒,但是当表有~20m行时,性能开始下降.我现在看到大约100个插入/秒.
桌子的大小不是特别大.对于20米行,磁盘上的大小约为500MB.
该项目是用Perl编写的.
这是SQLite中大型表的现实,还是有任何保密措施来维护 > 10m行的表的高插入率?
SQLITE_FCNTL_CHUNK_SIZE
:我不知道C(?!),所以我不想仅仅为了完成这项工作而学习它.我看不到使用Perl设置此参数的任何方法.继蒂姆的建议,一个指数,尽管SQLite的的说法,它能够处理大型数据集导致越来越缓慢插入时间,我进行以下设置的基准进行比较:
cache_size
pragma:10,000page_size
实用语:4,096temp_store
pragma:记忆journal_mode
pragma:删除synchronous
pragma:关闭在我的项目中,与下面的基准测试结果一样,创建了基于文件的临时表,并使用了SQLite对导入CSV数据的内置支持.然后将临时表附加到接收数据库,并使用insert-select
语句插入50,000行的集合
.因此,插入时间不会将文件反映到数据库插入时间,而是反映
表到表的插入速度.考虑CSV导入时间会使速度降低25-50%(非常粗略估计,导入CSV数据不需要很长时间).
显然有一个索引会导致插入速度随着表格大小的增加而减慢.
从上面的数据可以清楚地看出,正确的答案可以分配给Tim的答案,而不是SQLite无法处理它的断言.显然,如果索引该数据集不是您的用例的一部分,它可以处理大型数据集.我一直在使用SQLite作为日志记录系统的后端,暂时 …
我有一个大约30000行数据的文件,我想加载到sqlite3数据库.有没有比为每行数据生成插入语句更快的方法?
数据以空格分隔,并直接映射到sqlite3表.是否有任何类型的批量插入方法用于向数据库添加卷数据?
如果它没有内置,有没有人设计出一些狡猾的好方法呢?
我应该先问一下,有没有一种C++方法可以从API中做到这一点?
我听说过SQLite准备好的语句可以提高性能.我写了一些代码来测试它,并没有看到使用它们的性能有任何差异.所以,我想也许我的代码不正确.如果您发现我这样做有任何错误,请告诉我......
[self testPrep:NO dbConn:dbConn];
[self testPrep:YES dbConn:dbConn];
reuse=0
recs=2000
2009-11-09 10:39:18 -0800
processing...
2009-11-09 10:39:32 -0800
reuse=1
recs=2000
2009-11-09 10:39:32 -0800
processing...
2009-11-09 10:39:46 -0800
-(void)testPrep:(BOOL)reuse dbConn:(sqlite3*)dbConn{
int recs = 2000;
NSString *sql;
sqlite3_stmt *stmt;
sql = @"DROP TABLE test";
sqlite3_exec(dbConn, [sql UTF8String],NULL,NULL,NULL);
sql = @"CREATE TABLE test (id INT,field1 INT, field2 INT,field3 INT,field4 INT,field5 INT,field6 INT,field7 INT,field8 INT,field9 INT,field10 INT)";
sqlite3_exec(dbConn, [sql UTF8String],NULL,NULL,NULL);
for(int i=0;i<recs;i++){
sql = @"INSERT INTO test (id,field1,field2,field3,field4,field5,field6,field7,field8,field9,field10) VALUES (%d,1,2,3,4,5,6,7,8,9,10)";
sqlite3_exec(dbConn, [sql UTF8String],NULL,NULL,NULL);
} …
Run Code Online (Sandbox Code Playgroud) 我在我的一个项目中使用SQLite3,我需要确保插入到表中的行对于它们的一些列的组合是唯一的.在大多数情况下,插入的行在这方面会有所不同,但如果匹配,新行必须更新/替换现有行.
显而易见的解决方案是使用复合主键,并使用conflict子句来处理冲突.在此之前:
CREATE TABLE Event (Id INTEGER, Fld0 TEXT, Fld1 INTEGER, Fld2 TEXT, Fld3 TEXT, Fld4 TEXT, Fld5 TEXT, Fld6 TEXT);
Run Code Online (Sandbox Code Playgroud)
成了这个:
CREATE TABLE Event (Id INTEGER, Fld0 TEXT, Fld1 INTEGER, Fld2 TEXT, Fld3 TEXT, Fld4 TEXT, Fld5 TEXT, Fld6 TEXT, PRIMARY KEY (Fld0, Fld2, Fld3) ON CONFLICT REPLACE);
Run Code Online (Sandbox Code Playgroud)
这确实强制执行我需要它的唯一性约束.不幸的是,这种变化也会导致性能损失超出我的预期.我使用sqlite3
命令行实用程序进行了一些测试,以确保我的其余代码中没有错误.测试涉及在单个事务中或在每个1,000行的100个事务中输入100,000行.我得到了以下结果:
| 1 * 100,000 | 10 * 10,000 | 100 * 1,000 |
|---------------|---------------|---------------|
| Time | CPU | Time | CPU | Time | CPU …
Run Code Online (Sandbox Code Playgroud) 我读了包裹了很多SELECT
入BEGIN TRANSACTION/COMMIT
是一个有趣的优化.
但是,如果我PRAGMA journal_mode = OFF
之前使用" ",这些命令真的是必要的吗?(如果我记得的话,禁用日志,显然也禁用交易系统.)
sqlite ×8
insert ×3
performance ×3
c ×2
database ×2
sql ×2
bulk ×1
c++ ×1
feof ×1
file ×1
optimization ×1
orm ×1
portability ×1
python ×1
sqlalchemy ×1
syntax ×1
transactions ×1
while-loop ×1