【问题标题】:optimize SQLite read of all records优化 SQLite 读取所有记录
【发布时间】:2015-05-12 18:30:06
【问题描述】:

问题摘要

我可以很快地从单列表的单列中读取所有值。我怎样才能从一个表的单个列中快速读取所有值?

详情

我正在使用 C++ api 读取一个 sqlite 数据库,其中包含一个包含 220 万条记录的表。

数据有一个“坐标”列和(可选)其他几个列。 “坐标”列是一个 BLOB,目前总是 8 个字节长。其他列是 TEXT 和 REAL 的混合,TEXT 字符串从几个字符到大约 100 个字符不等(长度因记录而异)。

在一项实验中,我创建了包含“坐标”列以及大约 15 个其他列的表格。数据库文件总大小为 745 MB。我做了一个简单的

int rc = sqlite3_exec( db, "select coordinates from facilities", ReadSQLiteCallback, NULL, &errorMessage );

执行耗时 91 秒。

然后我创建了只有“坐标”列而没有其他数据列的表。数据库文件总大小为 36 MB。我运行了相同的 select 语句,耗时 1.23 秒。

我试图了解造成这种速度上的巨大差异的原因,以及当表中有这些额外的数据列时如何提高速度。

我确实理解更大的文件意味着需要读取更多的数据。但我预计减速在最坏的情况下或多或少与文件大小呈线性关系(即,它可能需要 1.23 秒的 20 倍,或大约 25 秒,但不是 91 秒)。

问题第一部分

我没有在文件上使用索引,因为通常我倾向于一次读取整个“坐标”列的大部分或全部,就像上面的简单选择一样。所以我真的不需要索引来排序或快速访问记录的子集。但是,也许拥有索引可以帮助引擎在读取所有数据时更快地从一个可变大小的记录移动到下一个?

还有其他简单的想法可以帮助减少这 91 秒吗?

问题第二部分

假设没有灵丹妙药可以将 91 秒(包括 15 个其他数据列)降低到接近 1.23 秒(仅存在坐标列)在单个表中,似乎我可以使用多个表,将坐标放在一个表中,将其余字段(我不需要如此快速的访问)放在另一个表中。

这听起来可能是外键的用途,但似乎我的情况并不一定需要外键的复杂性,因为我在坐标表和其他表之间有一个简单的一对一对应关系数据表——坐标表的每一行对应于另一个数据表的相同行号,所以这就像我将每条记录“拆分”到两个表中一样。

所以问题是:我当然可以自己管理这种拆分,方法是为我的每条记录在两个表中添加一行,并从两个表中删除一行以删除记录。但是有没有办法让 SQLite 为我管理这种拆分(我在 google 上搜索了“sqlite split record across tables”但没有找到太多)?

【问题讨论】:

    标签: c++ sqlite select


    【解决方案1】:
    1. 索引通常用于搜索和排序。 但是,如果查询中实际使用的所有列都是单个索引的一部分,则您有一个covering index,并且可以在不访问实际表的情况下执行查询。

      coordinates 列上的索引可能会加快此查询的速度。

    2. 即使是 1:1 的关系,您仍然需要知道哪些行是关联的,因此您仍然需要一个表中的外键。 (这也恰好是主键,因此实际上您只需在两个表中重复主键列。)

      如果您没有 INTEGER PRIMARY KEY,您可以使用 internal ROWID 代替您的主键。

    【讨论】:

    • 对于 2,我不清楚为什么需要外键。当我在两个表中添加一条记录时,它会添加到两个表的末尾,所以两个表中的新行号是相同的,对吧?如果我从两个表中删除第 M 行,它是针对同一条记录的,并且所有其他行号都保持一致,对吗?所以我总是知道当我使用坐标表的第 N 行时,相应的数据在另一个数据表的第 N 行,对吧?还是按我想象的方式不能保证物理记录顺序?
    • 阅读更多,看起来我可以在插入时明确指定 rowId。所以我可以在坐标表中插入一条记录并使用 sqlite3_last_insert_rowid() 找到 rowId,然后将相应的数据插入到另一个明确指定 rowId 的日期表中。看起来应该可以,不是吗?
    • 是的,rowid就是行号。
    • 作为进一步说明,我将 MY_RECORD_ID INTEGER PRIMARY KEY 作为两个表中的第一个字段。这似乎是必要的,因为内部 rowid 值可以在 VACUUM 操作期间更改,而 MY_RECORD_ID 值不会更改。 (但是,MY_RECORD_ID 似乎以其他方式代替了内部 rowid。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 2018-01-17
    • 2019-07-28
    • 2021-09-29
    相关资源
    最近更新 更多