Sql 有没有办法优化一个查询,将两个内部连接到同一个表中?

Sql 有没有办法优化一个查询,将两个内部连接到同一个表中?,sql,sqlite,Sql,Sqlite,我有一个问题: 我有一个模型,上面有三张表: 林哈、卢瓦里奥和鲁阿 我有Linha表的参考id和一个Rua的参考id。 在我的代码中,我收到了两个关于idRua的参数,我必须返回所有Linhas,其中我有两个idRua的引用。。。在这个例子中,我有idRua=1和idRua=2 SELECT l.codigo, l.linha, l.idEmpresa, l.idLinha FROM Linha l INNER JOIN Itinerario i1 ON i1.idLinha = l.idL

我有一个问题: 我有一个模型,上面有三张表: 林哈、卢瓦里奥和鲁阿 我有Linha表的参考id和一个Rua的参考id。 在我的代码中,我收到了两个关于idRua的参数,我必须返回所有Linhas,其中我有两个idRua的引用。。。在这个例子中,我有idRua=1和idRua=2

SELECT l.codigo, l.linha, l.idEmpresa, l.idLinha 
FROM Linha l 
INNER JOIN Itinerario i1 ON i1.idLinha = l.idLinha 
INNER JOIN Itinerario i2 ON i2.idLinha = l.idLinha 
WHERE i1.ida = i2.ida and i1.idRua = 1 and i2.idRua = 2 
ORDER BY l.linha
问题是我在该表中得到了2个内部联接,查询速度变慢了。。。 有没有办法优化它? 是否存在具有“AND”条件或类似情况的“IN”运算符?
我正在使用SQLite。

您的查询将尽可能高效地表达出来。您需要确保有正确的索引,以便SQLite高效地执行查询。确保
inverio
表的
idLinha
列上存在索引:

create index Itinerario_Linha_Idx on Itinerario(idLinha)
idRua
上的索引也可能很有用:

create index Itinerario_Rua_Idx on Itinerario(idRua)

由于您的
WHERE
条件不适用于表
Linha
,因此您可以通过将这些条件移动到相关的
ON
子句中来提高性能,在进行内部联接时,可以在该子句中应用这些条件,而不是在结果集上:

SELECT l.codigo, l.linha, l.idEmpresa, l.idLinha 
FROM Linha l 
INNER JOIN Itinerario i1 ON i1.idLinha = l.idLinha and i1.idRua = 1
INNER JOIN Itinerario i2 ON i2.idLinha = l.idLinha and i2.idRua = 2 and i1.ida = i2.ida
ORDER BY l.linha
此外,您必须在
巡回(idLinha)
上有一个索引。几乎可以肯定的是,在
internerio(idRua)
上建立索引不会有什么帮助

为获得上述查询的最佳性能,请在
idLinha
idRua
上创建索引:

create index Itinerario_Index1 on Itinerario(idLinha, idRua);

ON
子句中同时使用
idLinha
idRua
,索引的两个部分都可以使用,因此数据库将只读取它需要的精确行,从而最小化I/O。

可能有一种方法可以消除自连接

如果我没有看错的话,那么您需要的是来自巡回的idLinha,它包含同一ida的idRua=1和idRua=2。我注意到这只是一个过滤条件,因为select中的所有内容都来自linha

以下内容获取此条件:

SELECT idlinha
From itinerario
GROUP BY idlinha, ida
having max(case when idRua = 1 then 1 else 0 end) = 1 and
       max(case when idRua = 2 then 1 else 0 end) = 1
现在,我们可以在“in”或“join”子句中使用它,如:

SELECT l.codigo, l.linha, l.idEmpresa, l.idLinha 
FROM Linha l
where l.idlinha in (SELECT idlinha
                    From itinerario
                    GROUP BY idlinha
                    having max(case when idRua = 1 then 1 else 0 end) = 1 and
                           max(case when idRua = 2 then 1 else 0 end) = 1
                   )
order by l.linha

分组方式可能比自加入快。

Hmm。。。我不太擅长数据库技能。。。所以也许这就是我不太了解这些东西的原因。。。当你说检查索引是否存在时,我的意思是我必须创建索引,对吗?但是如果我将表id创建为主键整数。。。它还没有被用作性能的索引?@Igor当我说“确保索引存在”时,我的意思是你应该创建一个索引,除非你已经创建了一个。的确,索引是在声明为主键的列上创建的;但是,
idLinha
idRua
都不是主键,因此在它们上添加索引应该会有所帮助。@Igor这很奇怪。这些表中有多少数据?@Igor与表中的总行数相比,
inveriorio
中有多少不同的
ida
值?我在这个问题中使用了另一个解决方案,我得到了2秒的响应。。。看看那里。。。非常感谢你的帮助!我试过了。。。比以前好多了。。但是我还是慢了下来。。20秒。。。对于将28848个数据输入到巡回表中。。。遇到Android谢谢你的帮助!!我用过戈登的溶液。我在2秒内得到了回应。。。真的谢谢!!我做到了。。。我的查询时间从20秒开始。。。只有2秒钟。。。您知道2个选择比自连接更有效的原因吗?