Sql 有没有办法优化一个查询,将两个内部连接到同一个表中?
我有一个问题: 我有一个模型,上面有三张表: 林哈、卢瓦里奥和鲁阿 我有Linha表的参考id和一个Rua的参考id。 在我的代码中,我收到了两个关于idRua的参数,我必须返回所有Linhas,其中我有两个idRua的引用。。。在这个例子中,我有idRua=1和idRua=2Sql 有没有办法优化一个查询,将两个内部连接到同一个表中?,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
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个选择比自连接更有效的原因吗?