3

私はその問題を抱えています:私はこれらの3つのテーブルを持つモデルを持っています:Linha、Itinerario、Rua Into Itinerario 私はLinhaテーブルへの参照IDとRuaのIDを持つ1つの参照を持っています。私のコードでは、idRua に関する 2 つの引数を受け取り、両方の idRua を持つ Rua の参照 Itinerario を持っているすべての Linhas を返さなければなりません... この例では、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

自己結合をなくす方法があるかもしれません。

私がこれを正しく読んでいれば、同じ ida に対して idRua = 1 と idRua = 2 の両方を含む Itinerario の idLinha が必要です。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

group by は、self-join よりも高速になる可能性があります。

于 2012-05-26T02:42:28.550 に答える
2

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

また、にインデックスが必要Itinerario(idLinha)です。のインデックスはItinerario(idRua)ほぼ間違いなく役に立ちません。

上記のクエリで最高のパフォーマンスを得るには、との両方 idLinhaにインデックスを作成しidRuaます。

create index Itinerario_Index1 on Itinerario(idLinha, idRua);

idLinhaと句idRuaの両方ONを使用すると、インデックスの両方の部分を使用できるため、データベースは必要な正確な行のみを読み取り、I/Oを最小限に抑えます。

于 2012-05-26T00:48:37.277 に答える
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 に答える