OT: SQL optimieren

18/03/2014 - 11:41 von Wolfgang Wolf | Report spam
Hallo,

habe da mal eine grundsàtzliche Frage zu einer SQL-Abfrage. Ich möchte
Datensàtze importieren und danach abfragen. Die Daten sehen vereinfacht
wie folgt aus:

ID Eigenschaft Wert
1 A 100
1 B 200
1 C 300

2 A 101
2 B 202

3 A 103
3 B 104
3 C 105

im Klartext: ein Artikel mit einer ID kann eine oder n Eigenschaften
besitzen. Jede Eigenschaft hat einen Wert. Primàrindex dieser Tabelle
wàre also ID+Eigenschaft, diese Kombination ist eindeutig.

Nun möchte ich alle IDs selektieren bei denen die Eigenschaft A = 100
und die Eigenschaft B = 200 ist. Das trifft also nur auf die ID 1 zu.

Eine SQL Abfrage in der Form

SELECT ID FROM t WHERE
(Eigenschaft = A AND Wert = 100)
AND
(Eigenschaft = B AND Wert = 200)

liefert keine Ergebnisse, ist auch klar warum nicht.

Korrekte Ergebnisse bekomme ich mit:

SELECT ID FROM t WHERE
ID IN (SELECT ID FROM t WHERE Eigenschaft = A AND Wert = 100)
AND
ID IN (SELECT ID FROM t WHERE Eigenschaft = B AND Wert = 200)

Das ist bei entsprechend vielen Datensàtzen (500.000) recht langsam,
zumal in die Abfrage ggf. mehrere Eigenschaften eingehen werden und
statt den ANDs auch irgendwelche ORs dabei sein könnten. Wie kann man so
was "optimieren"?

Schönen Gruß
W. Wolf
 

Lesen sie die antworten

#1 Hans Schlonies
18/03/2014 - 12:47 | Warnen spam
Am 18.03.2014 11:41, schrieb Wolfgang Wolf:

Korrekte Ergebnisse bekomme ich mit:

SELECT ID FROM t WHERE
ID IN (SELECT ID FROM t WHERE Eigenschaft = A AND Wert = 100)
AND
ID IN (SELECT ID FROM t WHERE Eigenschaft = B AND Wert = 200)

Das ist bei entsprechend vielen Datensàtzen (500.000) recht langsam,
zumal in die Abfrage ggf. mehrere Eigenschaften eingehen werden und
statt den ANDs auch irgendwelche ORs dabei sein könnten. Wie kann man so
was "optimieren"?



Um so eine Abfrage optimieren zu können, müßte man mehr über die
Problemstellung(en) an sich wissen.

Ich selber würde solch ein Statement, selbst bei einer so kleinen
Tabelle, niemals benutzen, weil das extrem auf die Performance geht.

Als Pragmatiker würde ich das oben geschilderte Problem einfach mit
einem schnöden

SELECT ID FROM t WHERE
(Eigenschaft = A AND Wert = 100) OR (Eigenschaft= B AND Wert = 200)

und anschließender Prüfung im Code ob zwei Werte anliegen abfackeln,
was sicherlich um Lichtjahre schneller wàre.

Ein zusàtzlicher Index könnte auch helfen.

Man könnte die Abfrage auch in einer SPL speichern und erst einen
Count(*) absetzen, bevor man sich die Daten holt, etc...

Ich halte es auch grundsàtzlich für wenig sinnvoll, alles mit einem
Statement abfackeln zu wollen. Oftmals laufen einzelne Statements
deutlich schneller ab. (Und sind meist auch besser lesbar...)

Gruß

Ähnliche fragen