如何在Qt应用程序中调试SQLite查询?



Qt的QSqlDatabase可以使用SQLite作为后端。我试图找出如何在Qt应用程序中运行时正确调试和优化我的SQLite查询(尤其是它们的执行时间(。尤其是当它们在通常的SQLite客户端(例如sqlite3命令行客户端(和Qt应用程序中的行为之间存在差异时,这一点是相关的。

通常的调试和诊断技术在这种情况下不再有效;例如,我不能使用 dot 命令来获取有关索引、跟踪执行时间等的信息,因为这些命令特定于sqlite3CLI 软件。

以下是我发现最有用的技术:

  1. 使用 CLI。最明显的是使用sqlite3命令行客户端连接到您从应用程序中使用的同一数据库,并在那里查找有关索引等的信息。它还有助于将通过Qt执行时不起作用的查询粘贴到那里,以便获得更详细的错误消息。显然,当错误是由于Qt内部使用的SQLite3库与系统库的差异而导致时,这种技术将不起作用。

  2. 使用 DB Browser for SQLite。开源数据库浏览器 SQLite (sqlitebrowser( 非常适合调试在 Qt 桌面应用程序中发生的 SQLite 查询问题,但不发生在sqlite3CLI 工具中。因为这个工具是用Qt本身制作的,可以从Ubuntu存储库(sudo apt install sqlitebrowser(安装,所以它使用的Qt与你在该系统上开发桌面使用的Qt应用程序时使用的Qt相同。这样,它还使用 Qt 本身使用的 ame SQLite 库,无论是系统的 SQLite 库还是 Qt 的捆绑 SQLite 库(这取决于 Qt 的编译方式(。

    请注意,使用默认设置,在sqlitebrowser中执行查询所需的时间是sqlite3CLI 或 Qt 应用程序中的 ~4 倍。对于所有查询,这大致成比例,因此仍可用于提高查询效率。它可能可以在软件的"PRAGMA"设置页面上进行更改。

  3. 使用杂注函数。在Qt应用程序中运行诊断SQLite查询时的一个困难是如何获取它们的输出。控制台上不会有来自 SQLite 库的调试消息。但幸运的是,大多数产生输出的 PRAGMA 查询(即诊断查询(也可以作为 PRAGMA 函数在 SELECT 查询中使用。这样,您可以在 SELECT 查询的表结果中返回有关索引等的信息。

  4. 使用EXPLAIN查询。SQLiteEXPLAIN QUERY PLAN查询(在较小程度上也是EXPLAIN查询(对于分析查询速度慢的原因非常有用。在sqlite3CLI 软件中运行时,EXPLAIN QUERY PLAN查询会生成绘制到屏幕上的树状图。因此,它似乎不是可以从Qt的SQL实现内部使用的查询,但这确实有效。因为这表示实际的表格数据,从在任何不是sqlite3CLI 的 SQLite 客户端中运行此类查询可以看出。示例输出:

    EXPLAIN QUERY PLAN SELECT [...];
    id  parent  notused detail
    6   0   0   SEARCH TABLE products USING COVERING INDEX idx_code (code=?)
    10  0   0   SEARCH TABLE product_categories USING PRIMARY KEY (product_id=?)
    20  0   0   SEARCH TABLE categories USING INTEGER PRIMARY KEY (rowid=?)
    
  5. 重新编译 SQLite 进行调试。最极端的措施是在启用调试的情况下重新编译Qt的SQLite3库,然后使用PRAGMA vdbe_debug=1;打开调试输出。这应该在查询运行时将调试输出打印到stdout。(我没有对此进行测试,可能仍然是Qt拦截了此输出。但可能不是。

最新更新