【发布时间】: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”但没有找到太多)?
【问题讨论】: