3

我有这个问题:我有一个包含这 3 个表的模型:Linha、Itinerario 和 Rua 在我的代码中,我收到了两个关于 idRua 的参数,并且我必须返回所有 Linhas,其中我有 Itinerario 对 Rua 的引用和两个 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

问题是我在该表 Itinerario 中获得了 2 个内部连接,并且查询变慢了......有什么办法可以优化它吗?是否有一些带有“AND”条件的“IN”运算符或类似的东西?我正在使用 SQLite。

4

3 回答 3

4

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

如果我没看错的话,你希望 Itinerario 中的 idLinha 包含同一个 ida 的 idRua = 1 和 idRua = 2。我注意到这只是一个过滤条件,因为选择中的所有内容都来自 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

group by 可能会比自加入更快。

于 2012-05-26T02:42:28.550 回答
2

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

create index Itinerario_Linha_Idx on Itinerario(idLinha)

上的索引idRua也可能派上用场:

create index Itinerario_Rua_Idx on Itinerario(idRua)
于 2012-05-26T00:44:12.220 回答
2

因为您的WHERE条件不适用于 table 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

此外,您必须在Itinerario(idLinha). 几乎可以肯定,索引Itinerario(idRua)无济于事。

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

create index Itinerario_Index1 on Itinerario(idLinha, idRua);

使用 bothidLinhaidRuainON子句,索引的两个部分都可以使用,因此数据库将只读取它需要的确切行,从而最大限度地减少 I/O。

于 2012-05-26T00:48:37.277 回答