我正在 SQLite 中创建一个数据库,如下所示:
QSqlQuery create_address;
create_address.prepare("CREATE TABLE addresses (addressid INTEGER PRIMARY KEY AUTOINCREMENT, address TEXT UNIQUE)");
QSqlQuery create_devices;
create_devices.prepare("CREATE TABLE devices (ch TEXT PRIMARY KEY, addressid INTEGER REFERENCES addresses(addressid))");
create_devices.exec();
create_address.exec();
我需要多次访问这个数据库(~660'000)通过
ch
并检索相应的地址,通过的ch
无法在数据库中(返回空字符串)。
为此,我提出了以下查询:
//outside loop
QSqlQuery find_address;
find_address.prepare("SELECT address FROM addresses,devices WHERE devices.addressid = addresses.addressid AND devices.ch = :chcode");
//in loop
find_address.bindValue(":chcode",QString::fromStdString(ch_code));
find_address.exec();
问题是这个过程非常慢(几乎需要12分钟才能完成所有660,000个搜索)。
在此之前,我尝试过使用
INNER JOIN
,但性能几乎相同。
是否有更好的方法来编写查询和/或构建数据库以获得更快的执行时间?
由于 SQL 查询有循环,因此可以将其包装到事务中,这可能会提高性能:
QSqlDatabase::database().transaction();
.........
// your loop
.........
QSqlDatabase::database().commit();
还可以通过添加索引来提高性能。在您的情况下,可以在字段
devices.addressid
和 devices.ch
上创建索引。在 sqlite 控制台中执行以下操作:
CREATE INDEX devices_index ON devices(ch, addressid);
如果没有对表格
addresses
和 devices
的外观进行任何测量或了解,就很难给出准确的建议。
也许连接是瓶颈,所以你可以尝试先创建一个视图。这将避免连接两个表 659000 次。 请参阅此处了解如何创建视图。
接下来(在黑暗中拍摄),不是执行 660000 个查询,而是进行批处理。例如,将
AND devices.ch = :chcode
替换为 AND devices.ch IN(:chcodelist)
并将多个 chcode 粘合在一起。根据内容,小心他们逃跑。