Es gibt noch eine andere Option: with
Syntax. Um das OP-Beispiel zu verwenden, würde dies folgendermaßen aussehen:
with data as (
select 'value1' name from dual
union all
select 'value2' name from dual
union all
...
select 'value10000+' name from dual)
select field1, field2, field3
from table1 t1
inner join data on t1.name = data.name;
Ich bin auf dieses Problem gestoßen. In meinem Fall hatte ich eine Liste von Daten in Java, wobei jeder Artikel eine item_id und eine customer_id hatte. Ich habe zwei Tabellen in der DB mit Abonnements für Artikel der jeweiligen Kunden. Ich möchte eine Liste aller Abonnements für die Artikel oder den Kunden für diesen Artikel zusammen mit der Artikel-ID erhalten.
Ich habe drei Varianten ausprobiert:
- Mehrfachauswahl aus Java (mit Tupeln, um das Limit zu umgehen)
- With-Syntax
- Temporärer Tisch
Option 1: Mehrfachauswahl aus Java
Grundsätzlich habe ich zuerst
select item_id, token
from item_subs
where (item_id, 0) in ((:item_id_0, 0)...(:item_id_n, 0))
Dann
select cus_id, token
from cus_subs
where (cus_id, 0) in ((:cus_id_0, 0)...(:cus_id_n, 0))
Dann erstelle ich eine Karte in Java mit der cus_id als Schlüssel und einer Liste von Elementen als Wert und füge für jedes gefundene Kundenabonnement (zu der Liste, die von der ersten Auswahl zurückgegeben wurde) einen Eintrag für alle relevanten Elemente mit dieser item_id hinzu. Es ist viel chaotischer Code
Option 2: With-Syntax
Holen Sie sich alles auf einmal mit einem SQL wie
with data as (
select :item_id_0 item_id, :cus_id_0 cus_id
union all
...
select :item_id_n item_id, :cus_id_n cus_id )
select I.item_id item_id, I.token token
from item_subs I
inner join data D on I.item_id = D.item_id
union all
select D.item_id item_id, C.token token
from cus_subs C
inner join data D on C.cus_id = D.cus_id
Option 3: Temporäre Tabelle
Erstellen Sie eine globale temporäre Tabelle mit drei Feldern: rownr (Primärschlüssel), item_id und cus_id. Fügen Sie dort alle Daten ein und führen Sie dann eine sehr ähnliche Auswahl wie Option 2 aus, verknüpfen Sie sie jedoch in der temporären Tabelle anstelle vonwith data
Performance
Dies ist keine vollständig wissenschaftliche Leistungsanalyse.
- Ich verwende eine Entwicklungsdatenbank mit etwas mehr als 1000 Zeilen in meinem Datensatz, für die ich Abonnements finden möchte.
- Ich habe nur einen Datensatz ausprobiert.
- Ich bin nicht am selben physischen Standort wie mein DB-Server. Es ist nicht so weit weg, aber ich merke, wenn ich es von zu Hause aus über das VPN versuche, ist alles viel langsamer, obwohl es die gleiche Entfernung ist (und es ist nicht mein Heim-Internet, das das Problem ist).
- Ich habe den vollständigen Aufruf getestet, daher ruft meine API einen anderen auf (der ebenfalls in derselben Instanz in dev ausgeführt wird), der ebenfalls eine Verbindung zur Datenbank herstellt, um den ursprünglichen Datensatz abzurufen. Das ist aber in allen drei Fällen gleich.
YMMV.
Die Option für temporäre Tabellen war jedoch viel langsamer. Wie im Doppel so langsam. Ich bekam 14-15 Sekunden für Option 1, 15-16 für Option 2 und 30 für Option 3.
Ich werde sie erneut im selben Netzwerk wie der DB-Server versuchen und prüfen, ob sich dadurch etwas ändert, wenn ich die Gelegenheit dazu bekomme.