【问题标题】:SQLite scanning table performanceSQLite 扫描表性能
【发布时间】:2013-01-23 12:03:36
【问题描述】:

我的表有以下字段:

  1. 日期(整数)
  2. 状态(整数)
  3. ProductId(整数)
  4. 产品名称(整数)
  5. 描述(文本)(最大文本长度 3000 个字符)

将有超过 800 万行。我需要决定是否应该将产品描述放在另一个表中。我的主要目标是让这个声明非常快:

SELECT Date,State,ProductId,ProductName FROM tablename ORDER BY DATE desc LIMIT 100

SQL 结果不会获取上述语句中的Description 字段值。只有在应用程序中选择了行时,用户才会看到描述(新查询)。

我真的希望在同一个表中包含产品描述,但我不确定 SQLite 如何扫描行。如果日期值不匹配,我会假设 SQLite 可以快速跳到下一行。或者它可能需要扫描该行的所有字段,直到它到达描述字段值的末尾才能知道该行已经结束?如果需要扫描所有字段才能到达下一行,Description字段中的3000个字符的值会大大降低速度吗?

编辑:不应使用索引,因为插入速度很重要。

编辑:尝试将所有内容都放在一个表中的唯一原因是我想在一个包含数百个项目的事务中执行 INSERT 和 UPDATE。可以在同一个事务中插入相同的项目并稍后更新,因此我无法知道每个项目的最后插入 id。

【问题讨论】:

  • 有多重要?查询中的索引加速通常比INSERTs 的任何减速要大得多。
  • 您是否实际测量过 INSERT 性能?
  • 是的,这在应用程序设计中是不可接受的。

标签: sql performance sqlite


【解决方案1】:
  1. 当您使用该查询并且在Date 列上没有索引时,SQLite 将从表中读取所有记录,并使用临时表对结果进行排序。
  2. 当您在Date 列上有索引时,SQLite 将查找索引中的最后 100 条记录,然后从表中读取这些记录的所有数据。
  3. 当你有一个covering index,即一个索引包含四个列 DateStateProductIdProductName,SQLite 将只读取索引中的最后 100 个条目。李>

每当 SQLite 从数据库文件中读取时,它不会读取值或记录,而是读取整个页面(通常为 1 KB 或 4 KB)。

在情况 1 中,SQLite 将读取表的所有页面。
在情况 2 中,SQLite 将读取索引的最后一页(因为 100 个日期将适合一页)和表的 100 页(每条记录一个,假设这些记录中没有两条恰好在同一页中)页)。
在第 3 种情况下,SQLite 将读取索引的最后几页。

案例 2 会比案例 1 快得多;案例 3 会更快,但可能不足以引起注意。

【讨论】:

  • 对不起,我忘了提到不应该使用索引。所以我的情况是 1,这意味着在扫描期间,无论日期值是否匹配,都会读取所有字段值。如果描述不超过 3000 个字符,这是否会产生太大的性能差异?谢谢。
  • 还有一个问题,如果顺序是按ROWID(而不是Date)按降序排列,在第1种情况下是否仍会进行全表扫描?
  • 查询示例:SELECT Date,State,ProductId,ProductName FROM tablename WHERE State=2 ORDER BY ROWID desc LIMIT 100
  • 这将使它向后遍历表并在 100 条输出记录后停止。
【解决方案2】:

我建议依靠旧的database normalization 规则,在这种情况下特别是1NF。如果要重复该描述(ProductName 也是如此),那么您有一个数据库设计问题,并且它在 SQLite 或其他中与它几乎没有关系。 CL 的索引是正确的,请注意,正确的索引仍然很重要。

查看您的模型,为产品制作一个表格,为库存制作另一个表格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 2020-10-02
    • 2011-12-21
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    相关资源
    最近更新 更多