【问题标题】:Massive performance difference between sqlite amalgamation 3.7 and 3.16sqlite 合并 3.7 和 3.16 之间的巨大性能差异
【发布时间】:2019-06-12 06:11:20
【问题描述】:

我有一个 MS Window 可执行文件,用非托管纯“C”编写,它在嵌入式数据库引擎 (SQLite) 周围放置一个 GUI 包装器。 SQLite 功能由合并包 3.7.14.1 提供 特别是 2 个文件 sqlite3.h 和 sqlite3.c 我对“开箱即用”文件所做的唯一更改是添加以下行: #define SQLITE_ENABLE_COLUMN_METADATA 1

它都是使用 Visual Studio 2008 在 Win 7(64 位)系统上编译的,但我将其编译为 32 位应用程序。

我已将文件 sqlite3.h 和 sqlite3.c 替换为合并包 3.15.2 中的文件 同样,唯一的变化是添加以下行: #define SQLITE_ENABLE_COLUMN_METADATA 1

我没有更改我的项目配置。我只交换了 2 个文件!

我有一个复杂的脚本,它将一个大约 600 MB 的大型 DB 加载到内存中,然后执行大量 SELECTS,并将结果传输到 Excel(使用我的 GUI 包装器中的功能)。

我的问题。使用合并包 3.7.14.1 的版本的性能比合并包 3.15.2 的版本性能一百倍以上。 我使用的是完全相同的“脚本”。

我尝试了合并包 3.16 并没有更好。 我可以看到性能损失在 SQL 引擎中(通过在进入和离开 SQL 机器时显示弹出窗口。 就我的 GUI 包装器、Visual Studio 配置、项目配置而言,一切都是一样的。 我认为性能问题在于合并包中的一些编译器开关。

有人知道我应该从哪里开始看吗?

【问题讨论】:

  • 你有索引吗?你能找出哪个查询负责吗?
  • 显示数据库架构。
  • 我在俄勒冈州立大学开源图书馆找到了合并包的副本。我现在用 13 个包(3.16 回到 3.08.01)重复了测试。在我的测试中,所有这些都显示出同样缺乏“开箱即用”的性能。我发现 3.7.17 是迄今为止处理我的测试的最佳版本。现在我会考虑在源代码级别比较 3.7.17 和 3.8.01。但这可能会超出我的范围,除非它是编译器开关。
  • 数据库由大约 90 多个表组成。没有索引。奇怪的是,至少对我来说,3.7.14 或 .17 与当前的 3.16 版本之间的性能是如此不同。在每种情况下,我都使用“开箱即用”的 sqlite3.c/h 文件,除了我的#define。
  • 一个典型的查询对于这个注释字段来说太大了,但是这个查询,只有 SELECT,大量使用了带通配符的 LIKE,并且有 52 行的形式,sum (CASE WHEN ("DTENDE KW" LIKE '%KW02%' ) THEN 1 ELSE 0 END) as KW02 一个典型的查询是 > 5000 个字符。

标签: sqlite preprocessor amalgamation


【解决方案1】:

这个问题可能是由 SQLite 的Next Generation Query Planner 引起的,它是在 3.8.0 版本中引入的。一旦你发现特定的查询速度很慢,你可以尝试以explain 为前缀运行它们。这将转储查询计划,让您查看 3.7.14 和 3.15.2 创建的计划的差异。

如果不查看查询或数据库,很难准确地说出问题出在哪里,但通常查询性能可以通过索引来提高,所以我首先会在计划中寻找可以通过添加索引来避免的任何表扫描。要尝试的另一件事是在您的数据库上运行analyze 以生成帮助规划器构建最佳查询计划的统计表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    • 2012-03-10
    • 1970-01-01
    • 2021-03-21
    相关资源
    最近更新 更多