【问题标题】:sqlite: Fastest way to get all rows (consecutive disk access)sqlite:获取所有行的最快方法(连续磁盘访问)
【发布时间】:2011-11-04 00:11:52
【问题描述】:
我想使用 system.data.sqlite 读取表中的所有行。由于我有一个非常大的表(> 450GB,> 60 亿行),我想确保 sqlite 将使用连续的磁盘访问。您可能知道随机访问硬盘很慢。由于内存限制,我无法一次加载所有数据。所以最好的方法是如果 sqlite 读取几百 MB(连续),然后我处理这个数据,sqlite 读取下一个。
我如何确定 sqlite 会以这种方式进行磁盘访问,而不是从硬盘上的一个位置跳转到另一个位置?
我知道的事情(我认为这些建议会出现):
- 最好使用其他 DBMS。但我想/需要用这个来解决它。
- 我知道在我处理数据时,操作系统会将磁盘磁头定位在其他数据上。这没关系。只是会连续读取几百MB。
- 我不想/可以将数据库文件拆分成更小的部分
我找到了这篇文章,但它没有正确解决我的问题:
Which is the fastest way to retrieve all items in SQLite?
【问题讨论】:
标签:
sqlite
system.data.sqlite
【解决方案1】:
这就是聚集索引的用途。 sqlite 不支持它们。
以下内容抄自:http://www.sqlite.org/cvstrac/wiki?p=PerformanceTuningWindows
四:聚集索引
SQLite 不支持聚集索引(简单地说,索引强制
数据库中的数据以相同的顺序物理放置
因为索引需要它。)
这意味着如果您的索引是顺序 INTEGER,则记录是
以 INTEGER 顺序物理布局在数据库中,1 然后 2
然后 3.
您无法创建聚集索引,但可以按顺序对数据进行排序
这样任何历史数据都可以很好地排序。当然,作为
数据库成熟了,你失去了它,但它有帮助
其他人发布了这个,这是一个很好的例子,所以我会的。
如果你有一个 WIBBLE 表,它的字段 KEY 你想访问很多,
如果一切都井井有条,那就太好了。使用命令行
工具,您可以通过执行以下操作创建一个假集群:
create table wibble2 as select * from wibble;
delete from wibble;
insert into wibble select * from wibble2 order by key;
drop table wibble2;
底线是您可以手动重新排序记录,但我想这对您来说只有在您不打算经常写入表格时才实用。
【解决方案2】:
在 SQLite 中,表行按rowid 排序存储,因此按此顺序读取行的最有效方法是按此列(或您使用 INTEGER PRIMARY KEY 声明的别名)排序:
SELECT * FROM wibble ORDER BY rowid
对于WITHOUT ROWID 表,您按主键列排序:
SELECT * FROM wibble ORDER BY MyPrimary, KeyColumns
【解决方案3】:
来自@CL。回复this post:
在 SQLite 中,使用 CREATE INDEX 创建的索引是非集群的
索引。
从 3.8.2 版本开始,SQLite 支持 WITHOUT ROWID 表,这些表是
聚集索引。