【问题标题】:SQLite performance on large tables大型表上的 SQLite 性能
【发布时间】:2015-11-02 21:12:12
【问题描述】:

编辑:我的错误非常基本:我没有使用 PRIMARY KEY 进行索引。为了使这个线程更有用一点,我添加了性能数据来搜索我的表,无论是否使用索引来进行性能比较。

我在 Windows 和 linux 下运行的应用程序中使用 python 中的 sqlite3。我的数据库文件目前在 700 MB 范围内。

我认识到我最大的表中的条目数量存在一个特殊的性能问题。它由 10 列整数和浮点数以及一个 varchar 组成。

该表有 1.6 个 Mio 行。对于该大小,每个 SELECT 或 UPDATE 命令需要 327 毫秒。这对我的应用程序来说太长了,因为它现在主要等待 sqlite。

我认识到,随着表大小的减小,性能会急剧提高。我发现:

  • 1.6M 条目 327 ms 不带索引 => 29.7 ms 带索引
  • 670k 条目 149 ms 不带索引 => 28.8 ms 带索引
  • 280k 条目 71 ms w/o indexing => 28.5 ms with indexing
  • 147k 条目 44 ms w/o indexing => 28.0 ms with indexing
  • 19k 条目 25 ms 不带索引 => 25.0 ms 带索引

结论:使用索引搜索时间几乎保持不变,而不使用索引的搜索时间几乎随着表大小线性上升。仅对于非常小的表,差异可以忽略不计。

【问题讨论】:

  • 你的架构是什么?您有什么疑问?你在使用索引吗?
  • 如果您找到了解决您自己问题的方法,请接受答案或添加您自己的答案。请不要用答案编辑您的问题。

标签: performance sqlite


【解决方案1】:

当查询时间与表大小呈线性关系时,您的查询可能会进行全表扫描,这意味着它们必须读取表中的所有行。这通常意味着他们不是using indexes

如果不查看架构和查询,我们无法告诉您应该索引什么。您可以通过将EXPLAIN QUERY PLAN 放在它前面(如EXPLAIN QUERY PLAN SELECT * FROM foo)来查看您的查询在做什么。如果您看到“SCAN TABLE”,那就是全表扫描。如果您看到正在使用索引的“USING INDEX”。

【讨论】:

  • 就是这样。抱歉,这是数据库技术的一个非常基本的问题。我只是没有使用我的索引进行搜索,这反过来意味着我需要为我的表选择一个更合适的索引。
【解决方案2】:

确保 SELECT 和 UPDATE 的 WHERE(和 JOIN,如果使用)子句中的每一列都出现在索引中,或者是表主键的一部分。

另请注意,索引带来的性能改进与查询结果的恒定大小相关。如果查询结果的数量随着表的大小线性增长,那么索引的效果就会受到限制,因为传输回应用程序的结果数据量不能有意义地减少。在这种情况下,您可能需要进行更深入的性能分析。

【讨论】:

  • JOIN 字段也应该被索引。
  • 是的。我忘了他们。
猜你喜欢
  • 2018-03-06
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 2012-04-19
  • 2012-08-24
  • 1970-01-01
相关资源
最近更新 更多