【问题标题】:SQLite select by rowid with O(1) instead of O(log(N))?SQLite 通过 O(1) 而不是 O(log(N)) 的 rowid 选择?
【发布时间】:2019-05-17 17:29:41
【问题描述】:

我想知道是否可以创建一个 SQLite 数据库,我可以在其中使用 O(1) 将 select 行通过 rowid 进行。

我开始在我的一个项目中使用 sqlite 数据库,发现来自较大数据库的 selecting 行比来自较小数据库的 selecting 行花费的时间更长。我开始在网上搜索并偶然发现this article。显然,当selectrowid 调用时,SQLite 不会直接访问rowid,而是执行二分搜索以获取请求的rowid。这是一个非常合乎逻辑的解决方案,因为我们可以从数据库中删除行,在这种情况下,直接访问rowid 是行不通的。 但就我而言 - 我有一个“不可变”的数据库,在创建数据库之后我没有更改它;因此,所有rowid 都存在且顺序正确。

所以我在徘徊是否可以创建一个特殊的数据库或使用一个特定的查询命令告诉 SQLite 通过访问 rowid 而无需任何二进制搜索来选择。

如果有其他 SQLite 替代品可以更好地满足我的情况,请告知我(不过,在我的项目中,我无法将数据库加载到内存中,并且同时访问不同的数据库应该是即时的)

谢谢。

【问题讨论】:

  • 你试过 WITHOUT ROWID 表吗? - sqlite.org/withoutrowid.html
  • “我有一个“不可变”的数据库,在创建数据库后我不会更改它;“......是的,但是数据库(SQLite)应该如何知道并优化它......它不是只有 SQLite,当数据在 de 索引中变大(使用 B-tree)时,MySQL 也会使用更多 seeks。“如果 SQLite 有其他替代品可以更好地为我的情况执行”所以很可能其他 RDBMS 也适用使用 B-tree 索引时那样...
  • "如果 SQLite 有其他替代品可以更好地满足我的情况" 对于您没有提供表结构、示例数据和/或正在运行的查询的情况,我建议您阅读 @ 987654324@ 并为我们提供文本格式的示例数据、CREATE TABLE 语句和文本格式的预期结果......此外,您还应该告诉我们有多少用户连接到 SQLite 数据库以及 pyhon 应用程序或多或少是如何工作的跨度>
  • @RaymondNijland,我根据我在这个线程stackoverflow.com/questions/53483493/… 中得到的建议选择了 SQLite,我需要在不加载文件的情况下即时访问文件中的一行。既然我得到了关于 dbm 的建议,我可能会研究这个选项。
  • Sqlite rowid 表使用 B*-trees,因此具有 O(n) 查找时间。您无法更改此设置。

标签: python database sqlite


【解决方案1】:

我最终使用了mmap。因为我有数百万行相同长度的行,所以我只是将这些行保存到带有 mmap 的二进制文件中。然后访问 k 线我只是要求 mmap 从k * (length_of_line) 点读取。

我使用答案 here 中的 sn-p 代码快速测试解决方案,但我相信它可以比这个简单的代码进一步优化。

【讨论】:

    【解决方案2】:

    如果您不需要 SQLite 的全部功能,您可以使用 dbm 模块的简单哈希算法。它使用散列并且可以比 ISAM 索引执行得更好。但是你会失去排序(在 SQL 等其他功能中......)

    【讨论】:

    • 我所需要的只是一个可以按行号即时访问行的文件,而无需在内存中存储任何内容......也许我会检查 dbm。在我之前的帖子中,我问了一个类似的问题,并且普遍认为 SQLite 赢了。
    • @artembus:SQLite 非常快并且与 Python 的接口很好,因此它通常是一个自然的选择。但是如果你真的需要高性能,你甚至可以考虑一个专用的直接访问文件,这将确保 O(1) 访问时间......
    • @artembus:看了你之前的帖子,我真的觉得你需要的是建立一个每行的偏移量+长度的索引文件。
    • 感谢您的建议。我考虑过创建一个索引文件,但找不到任何好的文档,可能是因为我搜索了错误的术语。你能给我一些关于我应该研究哪些包/框架/方法的提示吗?我不想从 0 开始重建轮子,而且我确信有人已经创建了一些代码/存储库,我可以将其用作基础。
    • @artembus:我试图用谷歌搜索,但没有找到任何东西。这不是一个常见的用例,因为数据库是标准。也许您可以看看使用直接键/值散列的 NoSQL 解决方案。效率不如直接 line_number/line 访问,但无论如何 O(1)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    相关资源
    最近更新 更多