问题摘要
我可以很快地从单列表的单列中读取所有值。如何从具有多个其他列的表的单个列中快速读取所有值?
详情
我使用C ++ api来读取包含一个包含220万条记录的单个表的sqlite数据库。
数据有一个"坐标"列和(可选)其他几列。 "坐标" column是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秒。
我试图理解是什么导致速度的这种显着差异,以及当表格包含这些额外数据列时我如何提高速度。
我知道较大的文件意味着只需要阅读更多数据。但我认为减速最差或多或少与文件大小成线性关系(即它可能需要20倍于1.23秒,或大约25秒,但不是91秒)。
问题第一部分
我没有在文件上使用索引,因为通常我倾向于阅读整个"坐标的大部分或全部"如上所述的简单选择中的列。所以我真的不需要索引来排序或快速访问记录的子集。但也许有一个索引可以帮助引擎在读取所有数据时更快地从一个可变大小的记录移动到下一个记录?
还有其他简单的想法可能有助于减少那些91秒吗?
问题第二部分
假设没有神奇的子弹可以将91秒(当包含15个其他数据列时)降低到接近1.23秒(当只有坐标列存在时)在一张表中,似乎我可以使用多个表格,将坐标放在一个表格中,将其余字段(我不需要这样快速访问)放在另一个表格中。
这听起来像是用于外键,但看起来我的情况并不一定需要外键的复杂性,因为我在坐标表之间有一个简单的一对一对应关系另一个数据表 - 坐标表的每一行对应于另一个数据表的相同行号,所以它真的就像我' ve" split"两张表中的每条记录。
所以问题是:我当然可以自己管理这个拆分,通过在每个记录的两个表中添加一行,并从两个表中删除一行来删除记录。但是有没有办法让SQLite为我管理这个分裂(我用谷歌搜索" sqlite分隔记录表#34;但没有找到很多)?
答案 0 :(得分:2)
索引通常用于搜索和排序。 但是,如果查询中实际使用的所有列都是单个索引的一部分,则可以使用covering index,并且可以在不访问实际表的情况下执行查询。
coordinates
列上的索引可能会加快此查询速度。
即使使用1:1的关系,您仍然需要知道哪些行是关联的,因此您仍需要在一个表中使用外键。 (这也恰好是主键,所以实际上你只是在两个表中都复制了主键列。)
如果您没有INTEGER PRIMARY KEY,则可以使用internal ROWID代替主键。