具有子查询性能的SQLite查询

具有子查询性能的SQLite查询,sql,sqlite,Sql,Sqlite,我有一个到Sqlite数据库的下一个SQL查询: SELECT * FROM messages WHERE type IN (3) AND modem_id IN( SELECT device_id FROM client_devices WHERE client_id=0 AND device_id IN (7368859)) ORDER BY time_detected DESC LIMIT 1000 其中子查询带来单个数据行。查询在我的数据上执行大约7秒。单独的子查询执行

我有一个到Sqlite数据库的下一个SQL查询:

SELECT * FROM messages   WHERE type IN (3) AND modem_id IN( 
    SELECT device_id FROM client_devices WHERE client_id=0 AND device_id IN (7368859)) 
ORDER BY time_detected DESC LIMIT 1000
其中子查询带来单个数据行。查询在我的数据上执行大约7秒。单独的子查询执行时间少于1ms。但是如果我去掉子查询并将这个调制解调器id直接传递给查询:

SELECT * FROM messages   WHERE type IN (3) AND modem_id IN( 7368859) 
ORDER BY time_detected DESC LIMIT 1000
查询执行时间小于50毫秒

我被误解了什么

UPD: 查询:

SELECT * FROM  messages   WHERE  type IN (3) AND modem_id IN( SELECT 7368859) ORDER BY time_detected DESC LIMIT 1000
执行7秒。以及查询

SELECT * FROM  messages   WHERE  type IN (3) AND modem_id IN(7368859) ORDER BY time_detected DESC LIMIT 1000
执行44毫秒。 这就是问题所在

UPD:

查询计划:

explain query plan SELECT * FROM  messages   WHERE  type IN (3) AND modem_id IN( SELECT 7368859) ORDER BY time_detected DESC LIMIT 1000
"0" "0" "0" "SEARCH TABLE messages USING INDEX time4_idx (type=?)"
"0" "0" "0" "EXECUTE LIST SUBQUERY 1"

explain query plan SELECT * FROM  messages   WHERE  type IN (3) AND modem_id IN(7368859) ORDER BY time_detected DESC LIMIT 1000
"0" "0" "0" "SEARCH TABLE messages USING INDEX time3_idx (type=? AND modem_id=?)"
UPD:
在我的例子中,“modem_id In(*)和“type In(*)”都可以作为向量的标量,并且取决于程序逻辑,所以解决方案是让“type In(*)始终作为向量,在这之后,像“type In(-1,*)”这样的东西所有查询都会完美执行。

如果可以的话,尝试将其重新表述为一个
连接

SELECT m.*
FROM messages m JOIN
     client_devices cd
     ON cd.device_id = m.modemId
WHERE m.type = 3 AND cd.client_id = 0 AND cd.device_id = 7368859
ORDER BY m.time_detected DESC
LIMIT 1000;

根据您的描述,我怀疑
client\u设备(client\u id,device\u id)
as messages(modem\u id,type)
上的索引有助于查询。一个障碍是
ORDER BY`。

输入(选择…
中的子查询可能返回任意数量的行,因此数据库假设有许多行,并估计在该列表中查找
类型
会更快,而不是相反

当您知道子查询只返回一行时,将其写为:


messages表、clients\u devices表上的索引很小,并且还将client\u id作为主键。顺便说一句,客户端设备上的单独查询执行得非常快。我更新了问题,最简单的两个查询的结果非常不同。在我的例子中,“modem_id In(*)和“type In(*)都可以作为向量的标量,并且取决于程序逻辑,所以解决方案是让“type In(*)始终作为向量,像“键入(-1,*)”之类的东西,在这之后,所有查询都会完美执行。
SELECT m.*
FROM messages m JOIN
     client_devices cd
     ON cd.device_id = m.modemId
WHERE m.type = 3 AND cd.client_id = 0 AND cd.device_id = 7368859
ORDER BY m.time_detected DESC
LIMIT 1000;
... WHERE type = (SELECT ...)