优化SQLite很棘手.C应用程序的批量插入性能可以从每秒85次插入到每秒超过96,000次插入!
背景:我们使用SQLite作为桌面应用程序的一部分.我们有大量的配置数据存储在XML文件中,这些数据被解析并加载到SQLite数据库中,以便在初始化应用程序时进行进一步处理.SQLite非常适合这种情况,因为它速度快,不需要专门配置,数据库作为单个文件存储在磁盘上.
理由: 最初我对我所看到的表现感到失望.事实证明,SQLite的性能可能会有很大差异(对于批量插入和选择),具体取决于数据库的配置方式以及如何使用API.弄清楚所有选项和技术是什么并不是一件小事,所以我认为创建这个社区wiki条目以与Stack Overflow读者分享结果是谨慎的,以便为其他人节省相同调查的麻烦.
实验:我不是简单地谈论一般意义上的性能提示(即"使用事务!"),而是认为最好编写一些C代码并实际测量各种选项的影响.我们将从一些简单的数据开始:
我们来写一些代码吧!
代码:一个简单的C程序,它逐行读取文本文件,将字符串拆分为值,然后将数据插入SQLite数据库.在代码的这个"基线"版本中,创建了数据库,但我们实际上不会插入数据:
/*************************************************************
Baseline code to experiment with SQLite performance.
Input data is a 28 MB TAB-delimited text file of the
complete Toronto Transit System schedule/route info
from http://www.toronto.ca/open/datasets/ttc-routes/
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "sqlite3.h"
#define INPUTDATA "C:\\TTC_schedule_scheduleitem_10-27-2009.txt"
#define DATABASE "c:\\TTC_schedule_scheduleitem_10-27-2009.sqlite"
#define …Run Code Online (Sandbox Code Playgroud) 我知道sqlite对于非常大的数据库文件表现不佳,即使它们受支持(曾经在sqlite网站上发表评论,说明如果你需要的文件大小超过1GB,你可能要考虑使用企业rdbms.再找不到它,可能与旧版本的sqlite有关.
但是,出于我的目的,我想在考虑其他解决方案之前了解它到底有多糟糕.
我说的是数千兆字节的sqlite数据文件,从2GB开始.有人对此有经验吗?任何提示/想法?
我正在开发一个介于电子邮件服务和社交网络之间的Web应用程序.我觉得它有可能在未来发展壮大,所以我担心可扩展性.
我决定为每个活跃用户创建一个单独的SQLite数据库,而不是使用一个集中式MySQL/InnoDB数据库然后对其进行分区:每个"分片"一个活跃用户.
这样,备份数据库就像每天一次将每个用户的小型数据库文件复制到远程位置一样简单.
扩展将像添加额外的硬盘来存储新文件一样简单.
当应用程序超出单个服务器时,我可以使用GlusterFS在文件系统级别将服务器链接在一起并运行应用程序,或者构建一个简单的SQLite代理系统,允许每个服务器操作相邻服务器中的sqlite文件.
并发问题将是最小的,因为每个HTTP请求一次只能触及一个或两个数据库文件,成千上万,而SQLite只会阻止读取.
我敢打赌,这种方法可以让我的应用程序优雅地扩展,并支持许多很酷和独特的功能.我打错了吗?我错过了什么吗?
更新我决定采用一种不太极端的解决方案,到目前为止工作正常.我正在使用固定数量的分片 - 准确地说是256个sqlite数据库.通过简单的散列函数将每个用户分配并绑定到随机分片.
我的应用程序的大多数功能每个请求只需要访问一个或两个分片,但有一个特别需要在256到10个不同的分片上执行简单查询,具体取决于用户.测试表明,如果所有数据都缓存在RAM中,则需要大约0.02秒或更短的时间.我想我可以忍受这个!
UPDATE 2.0我移植应用到MySQL/InnoDB和能够得到有关规则请求相同的性能,但对于需要碎片步行一个请求时,InnoDB快4-5倍.出于这个原因,以及其他原因,我正在放弃这种架构,但我希望某个地方找到它的用途......谢谢.
我试图理解在使用BerkeleyDB时应该选择哪种访问方法:B-Tree与HashTable.Hashtable提供O(1)查找,但插入是昂贵的(使用线性/可扩展散列我们得到分摊O(1)插入).但B-Trees提供log N(base B)查找和插入时间.B-Tree还可以支持范围查询并允许按排序顺序进行访问.
我有一个约60GB的表,我正在尝试创建一个索引,它非常慢(几乎一天,仍在运行!)
我看到大部分时间都在磁盘I/O(4MB/s)上,而且它没有那么多使用内存或CPU
我试过:运行'pragma cache_zise = 10000'和'pragma page_zise = 4000'(在我创建表之后),它仍然没有帮助.
如何在合理的时间内运行"创建索引"?
我已经研究过关于SQLite和UnQLite的内容,但仍有一些问题尚未得到解答.UnQLite似乎在过去几年内已经发布,这归因于缺乏基准."性能"(读/写速度,查询,平均数据库大小在显着减速之前等)比较可能在某种程度上是苹果到橙子.
从我所看到的两个方面来看,两者之间的差异相对较小,即SQLite是一个关系数据库,而UnQLite是一个键值对和文档(通过Jx9)数据库.它们既可移植,又可跨平台,并且具有32/64位友好性,并且可以具有单写和多读连接.在UnQLite基准测试中可以找到很少的东西,而SQLite在各种(脚本)语言中有不同的实现.SQLite 在内存数据库,索引数据和具有不同数据大小的读/写模式下具有不同的性能.整体SQLite看起来快速可靠.
我在UnQLite上找到的所有东西都是不可靠和令人困惑的.我似乎找不到任何有用的东西.UnQLite似乎达到了什么读/写速度?使用UnQLite时,建议使用哪些语言?有哪些已知的缺点和错误?
如果它有助于解释我的阴谋,我正在开发一个网络实用程序,它将通过网络接口之间的热交换来读取和处理数据包.由于连接虽然不太可能达到最高1 Gbps的速度,但会有大量原始数据写入数据库.它仍然处于开发的早期阶段,我必须找到一种平衡性能的方法.有很多因素,例如丢失数据包,每个写入大小有多大,处理和移动数据的速度,需要多少组织,需要多少表,是否可以实现多处理,每个如何依赖数据库是关于硬盘速度等等.我的数据将需要表格,但我是否必须存储它们作为关系仍然在空中.看看这两者如何与自己的利弊相提并论(除了通常的KVP与关系辩论之外)可能会把我推向任何一方,或者,如果我已经足够疯狂,可以将两者结合起来
sqlite ×5
database ×2
performance ×2
architecture ×1
b-tree ×1
berkeley-db ×1
c ×1
hashtable ×1
optimization ×1
scalability ×1
sharding ×1
sql ×1
unqlite ×1