SQLite:实际限制是什么?

时间:2012-03-12 13:44:05

标签: sqlite select database-performance

在将此问题标记为重复之前,请听我说出来!
我已经阅读了有关如何提高性能的问题,例如仅举几个Improve INSERT-per-second performance of SQLite?What are the performance characteristics of sqlite with very large database files?

我正在努力使sqlite工作,数据库文件大小为5千兆字节。相反,有人在那里,声称sqlite对他们来说“很棒”,即使数据库大小高达160 GB。我自己没有尝试过,但是从提出的问题来看,我想所有的基准测试都可能只用数据库中的表来完成。

我正在使用带有
的数据库   - 20左右的表
  - 一半的桌子有超过15列   - 这些15个或每个列表中的每一个都有6/7个外键列   - 这些表中的一些已经在一个月内增长到拥有2700万条记录

我使用的开发机器是3 GHz四核机器,有4台RAM,但只需要3分钟就可以查询这些大表中的row_count。

我找不到任何水平分区数据的方法。我拥有的最佳镜头是将数据分成多个数据库文件,每个表一个。但在这种情况下,据我所知,外键列约束不能使用,所以我将不得不创建一个自足的表(没有任何外键)。

所以我的问题是 a)我是否使用错误的数据库进行工作? b)你觉得我哪里出错了? c)我还没有在外键上添加索引,但如果只是行计数查询需要4分钟,外键索引如何帮助我?

EDIT 提供更多信息,即使没有人要求它:) 我使用SQLite版本3.7.9与system.data.sqlite.dll版本1.0.77.0

EDIT2: 我认为我与160位演员的不同之处在于他们可以选择个人唱片或小范围的唱片。但是我必须在表中加载所有2700万行,将它们与另一个表连接起来,按照用户的要求对记录进行分组并返回结果。 有什么输入是为这种结果优化数据库的最佳方法。

我无法缓存先前查询的结果,因为它在我的情况下没有意义。点击缓存的可能性相当低。

3 个答案:

答案 0 :(得分:5)

这里有很多需要考虑的问题,但我的第一点建议是不要以面值来衡量其他的绩效统计数据。数据库性能取决于很多方面,包括数据库的结构,查询的复杂性,您定义(或不​​定义)的索引,以及通常只有大量数据。许多报告的性能数据来自大量的试验和错误,和/或将数据库与手头的工作相匹配。换句话说,你将从任何DBMS获得的性能不能明显地与另一个应用程序的性能进行比较,除非你的数据集和结构几乎完全相同 - 它们肯定是一个指南,也许是一个理想的努力,但你不一定会“开箱即用”。“

作为一个起点,我会开始索引那些非常大的表上的数据(看起来,从评论,你已经得到了),看看会发生什么。当然,计数花了四分钟是相当长的一段时间,但不要止步于此。添加一些索引,更改它们,询问您是否存储了不需要存储的数据,并查看其他数据库查询,而不仅仅是计数查询,以判断性能。 查找使用SQLite进行大量行的其他应用和博客帖子,看看他们为解决这些问题所做的工作(可能包括更改数据库)。基本上,尝试一下 - 然后做出判断。不要让最初的恐惧阻止你,以为你走错了路。也许你是,也许你不是,但不要只停留在COUNT查询。无论你如何切片,表中的2700万条记录都是垃圾。

最后,一个具体的建议是这样的:在SQLite中,不要将数据库拆分成多个文件 - 我没有看到帮助,因为那样你将不得不做很多额外的查询工作,然后在结果从多个查询返回后手动加入单独的表。这重塑了RDBMS为您所做的事情,这是一个疯狂的想法。你不会以某种方式找到一种比RDBMS系统的创建者更快地进行连接的方法 - 你肯定会在那里浪费时间。

答案 1 :(得分:0)

与其他DMBS相比,SQLite中的

select count(*)总是会变慢,因为它会对该特定请求进行表扫描。它没有统计表来帮助解决问题。这并不意味着您的应用程序查询会很慢。您需要测试您的查询以真正告诉您可以期待的内容。

一些通用指南:索引是绝对必须的,因为在涉及巨大的大小时,在二叉树中导航数据子集比遍历整个表要快得多。为了帮助加载时间,您应该为唯一索引排序数据,如果没有唯一索引,那么最大索引。如果您可以在加载之前删除索引并在之后将其放回,则会更快。如果这些技术无法满足您的操作和SLA参数,那么就可以进行水平分区,并使用“attach”跨越您需要的数据范围。 SQLite最多可以支持10个附件。我知道有人说分区是工具的工作,而不是开发人员,但是当你面临物理限制时,你必须卷起袖子或者选择一个商业工具来为你做掩护。

答案 2 :(得分:-1)

如果您在客户端直接部署了50MB或更多的数据库,则意味着您做错了什么。 尝试迁移到服务器端,同时在客户端存储密钥 - 重要值。 (仅参考) 你不会有实时,但至少它会产生一个合适的解决方案。 “服务器端”是您的问题的答案,即如果您放弃或优化实时要求,因为这就是您所拥有的(基于您的描述)。 在任何情况下。 SQLite几乎可以处理任何事情,但从个人经验来看,即使以实时结果为代价,也尽量保持简单。