Qt的QSqlDatabase可以使用SQLite作为后端。我试图找出如何在Qt应用程序中运行时正确调试和优化我的SQLite查询(尤其是它们的执行时间(。尤其是当它们在通常的SQLite客户端(例如sqlite3
命令行客户端(和Qt应用程序中的行为之间存在差异时,这一点是相关的。
通常的调试和诊断技术在这种情况下不再有效;例如,我不能使用 dot 命令来获取有关索引、跟踪执行时间等的信息,因为这些命令特定于sqlite3
CLI 软件。
以下是我发现最有用的技术:
-
使用 CLI。最明显的是使用
sqlite3
命令行客户端连接到您从应用程序中使用的同一数据库,并在那里查找有关索引等的信息。它还有助于将通过Qt执行时不起作用的查询粘贴到那里,以便获得更详细的错误消息。显然,当错误是由于Qt内部使用的SQLite3库与系统库的差异而导致时,这种技术将不起作用。 -
使用 DB Browser for SQLite。开源数据库浏览器 SQLite (
sqlitebrowser
( 非常适合调试在 Qt 桌面应用程序中发生的 SQLite 查询问题,但不发生在sqlite3
CLI 工具中。因为这个工具是用Qt本身制作的,可以从Ubuntu存储库(sudo apt install sqlitebrowser
(安装,所以它使用的Qt与你在该系统上开发桌面使用的Qt应用程序时使用的Qt相同。这样,它还使用 Qt 本身使用的 ame SQLite 库,无论是系统的 SQLite 库还是 Qt 的捆绑 SQLite 库(这取决于 Qt 的编译方式(。请注意,使用默认设置,在
sqlitebrowser
中执行查询所需的时间是sqlite3
CLI 或 Qt 应用程序中的 ~4 倍。对于所有查询,这大致成比例,因此仍可用于提高查询效率。它可能可以在软件的"PRAGMA"设置页面上进行更改。 -
使用杂注函数。在Qt应用程序中运行诊断SQLite查询时的一个困难是如何获取它们的输出。控制台上不会有来自 SQLite 库的调试消息。但幸运的是,大多数产生输出的 PRAGMA 查询(即诊断查询(也可以作为 PRAGMA 函数在 SELECT 查询中使用。这样,您可以在 SELECT 查询的表结果中返回有关索引等的信息。
-
使用
EXPLAIN
查询。SQLiteEXPLAIN QUERY PLAN
查询(在较小程度上也是EXPLAIN
查询(对于分析查询速度慢的原因非常有用。在sqlite3
CLI 软件中运行时,EXPLAIN QUERY PLAN
查询会生成绘制到屏幕上的树状图。因此,它似乎不是可以从Qt的SQL实现内部使用的查询,但这确实有效。因为这表示实际的表格数据,从在任何不是sqlite3
CLI 的 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=?)
-
重新编译 SQLite 进行调试。最极端的措施是在启用调试的情况下重新编译Qt的SQLite3库,然后使用
PRAGMA vdbe_debug=1;
打开调试输出。这应该在查询运行时将调试输出打印到stdout
。(我没有对此进行测试,可能仍然是Qt拦截了此输出。但可能不是。