Nicole Wagner
2011-03-02 10:33:56 UTC
Hallo User,
hier ist ein "gelöstes" Problem.
Doch es ist nicht mit SQL gelöst. Und das Problem hat ein Makel: Es hat
uns provoziert und ist in SQL noch immer ungeloest.
Als geistige Herausforderung poste ich es hier noch einmal.
=======================================================
Wie und warum ich selbst es "geloest" habe:
Ich habe via Delphi meine Query ex post gefiltert und das aus 2
Gruenden:
1) Viele Subselect oder group Formulierungen wurden in meiner DB extrem
langsam. Ich habe bevorzugt, ein schnelles Filter in Delphi zu setzen,
als etwas gegen die Langsamkeit einer einzigen Query zu unternehmen.
Denn etwa ein neuer Index macht mir die DB einige MB groesser. Das
heisst, ich muss beim Sichern ein paar Sekunden laenger warten. Etc.
2) Hier wurde der Verdacht geaeussert, den auch ich habe:
Firbird (2.1. und 1.5) hat einen Bug, wenn im Subselect "Find First n"
verwendet wird. Auch mit diesem schlage ich mich nicht mehr herum, wenn
ich das Problem erschlage. Feige, von hinten erschlage, ich gebe es zu.
Doch Hauptsache, es ist mal tot ;-)
=============================================================
Das ist die Basismenge per SQL abgefragt.
Die Abfrage ist OHNE Subselect blitzschnell.
(Sie wuerde aber mit Zugriff auf etwa comm im Subselect extrem langsam.
Dieses Comm scheint den join rueckabzuwickeln und produziert Millionen
von Zugriffen.)
Hier die schnelle:
s := 'select tbkurszeilen.fk_kontrakt as fk_kontrakt,' +
' tbkontrakte.name_ as name_,' +
' tbkontrakte.comm as comm,' +
' tbkurszeilen.fk_jdatum as fk_jdatum,' +
' tbkurszeilen.o as o,' +
' tbkurszeilen.h as h,' +
' tbkurszeilen.l as l,' +
' tbkurszeilen.c as c,' +
' tbkurszeilen.volume as volume,' +
' tbkurszeilen.openinterest as openinterest,' +
' tbkurszeilen.id_kurszeilen as id_kurszeilen,' +
' tbkurszeilen.trflag as Tradeflag' +
' from tbkurszeilen' +
' JOIN' +
' tbkontrakte on tbkurszeilen.fk_kontrakt =
tbkontrakte.id_kontrakt' +
' and tbkurszeilen.fk_jdatum = ' + QuotedStr(EIN_DATUM) +
' order by comm asc, openinterest desc;';
=======================================================================
So sieht sie ein Abfrageergebnis aus
(oups, ich hole ein paar Spalten raus, sonst bricht die Zeile um und es
wird unlesbar):
FK_KONTRAKT NAME_ COMM DATUM OPENINTEREST FK_TRADE ID_KURSZEILEN
9 ADH9 AD 15.01.2009 43100 5389569
8 ADM9 AD 15.01.2009 195 5389135
7 ADU9 AD 15.01.2009 153 5388716
127 BOH9 BO 15.01.2009 110591 5421170
126 BOK9 BO 15.01.2009 31438 5420779
125 BON9 BO 15.01.2009 27541 5420408
124 BOQ9 BO 15.01.2009 5777 5419928
122 BOV9 BO 15.01.2009 4166 5419152
123 BOU9 BO 15.01.2009 4145 5419551
591 BPH9 BP 15.01.2009 77632 5555000
590 BPM9 BP 15.01.2009 2573 5554642
589 BPU9 BP 15.01.2009 8 5554254
759 CH9 C 15.01.2009 336105 5597184
757 CN9 C 15.01.2009 127703 5596193
758 CK9 C 15.01.2009 112830 5596644
756 CU9 C 15.01.2009 32285 5595419
1073 CCH9 CC 15.01.2009 47045 5697131
1072 CCK9 CC 15.01.2009 31012 5696687
1071 CCN9 CC 15.01.2009 14286 5696265
1070 CCU9 CC 15.01.2009 7998 5695840
1299 CDH9 CD 15.01.2009 58319 5786183
1298 CDM9 CD 15.01.2009 2370 5785750
1297 CDU9 CD 15.01.2009 1250 5785329
1510 CLH9 CL 15.01.2009 382302 5870134
1507 CLM9 CL 15.01.2009 115975 5868804
1509 CLJ9 CL 15.01.2009 93297 5869589
1511 CLG9 CL 15.01.2009 61455 5870673
1508 CLK9 CL 15.01.2009 54640 5869101
1506 CLN9 CL 15.01.2009 52254 5868010
1505 CLQ9 CL 15.01.2009 27589 5867492
1504 CLU9 CL 15.01.2009 21408 5867130
1503 CLV9 CL 15.01.2009 21000 5866568
1502 CLX9 CL 15.01.2009 17542 5865986
1836 CTH9 CT 15.01.2009 69003 6008580
1835 CTK9 CT 15.01.2009 22724 6008069
1834 CTN9 CT 15.01.2009 19306 6007608
1833 CTV9 CT 15.01.2009 285 6007069
2142 CUH9 CU 15.01.2009 126198 6113378
2141 CUM9 CU 15.01.2009 1369 6112956
usw.
=======================================================
so SOLL es aussehen.
Von jedem Ding sollen genau jene max drei gewaehlt werden, die den
hoechsten openinterest Wert haben, also so:
FK_KONTRAKT NAME_ COMM DATUM OPENINTEREST ID_KURSZEILEN
9 ADH9 AD 15.01.2009 43100 5389569
8 ADM9 AD 15.01.2009 195 5389135
7 ADU9 AD 15.01.2009 153 5388716
127 BOH9 BO 15.01.2009 110591 5421170
126 BOK9 BO 15.01.2009 31438 5420779
125 BON9 BO 15.01.2009 27541 5420408
591 BPH9 BP 15.01.2009 77632 5555000
590 BPM9 BP 15.01.2009 2573 5554642
589 BPU9 BP 15.01.2009 8 5554254
759 CH9 C 15.01.2009 336105 5597184
757 CN9 C 15.01.2009 127703 5596193
758 CK9 C 15.01.2009 112830 5596644
1073 CCH9 CC 15.01.2009 47045 5697131
1072 CCK9 CC 15.01.2009 31012 5696687
1071 CCN9 CC 15.01.2009 14286 5696265
usw.
==================================================================
der Aufbau der Tabellen ist dieser:
Jeden Tag gibt es bestimmte Werte inklusive dem Wert "open interest".
Also z.B.
15.9.2009 .....oi=104735;
16.9.2009 ..... 124735...
17.9.2009 ..... 14735----
Wir wollen hier EINEN Tag ueber ALLE Werte betrachten.
WOHIN gehoert jetzt dieser Satz mit taeglichen Daten:
Dazu gibt es einen FK in jeder Tagezeile.
Dieser FK zeigt auf die Eckdaten der jeweiligen Kursreihe, wie
Rohstoff, Liefermonat, uam.
Das heisst, wir nehmen den Wert openinterest aus der Tabelle mit den
taeglichen Daten und die Informatione zu WELCHER Gruppe ein Datensatz
gehoert ueber den Fremdschluessel aus einer anderen Tabelle.
Raetselloeser: Bitte besonders Augenmerk auf den Join und das Fakt,
dass wir hier ZWEI Tabellennamen abfragen: tbkurszeilen und
tbkontrakte. Viele Zugriffe auf tbkurszeilen bremsen die Sache aus.
Also etwa comm im Subselect nach dem join ist nicht mehr akzeptabel vom
Tempo her.
Wie das dann gehen soll? - Ich habe keine Ahnung.
Darum filtere ich die Query schaebig via Delphi.
Nicole
hier ist ein "gelöstes" Problem.
Doch es ist nicht mit SQL gelöst. Und das Problem hat ein Makel: Es hat
uns provoziert und ist in SQL noch immer ungeloest.
Als geistige Herausforderung poste ich es hier noch einmal.
=======================================================
Wie und warum ich selbst es "geloest" habe:
Ich habe via Delphi meine Query ex post gefiltert und das aus 2
Gruenden:
1) Viele Subselect oder group Formulierungen wurden in meiner DB extrem
langsam. Ich habe bevorzugt, ein schnelles Filter in Delphi zu setzen,
als etwas gegen die Langsamkeit einer einzigen Query zu unternehmen.
Denn etwa ein neuer Index macht mir die DB einige MB groesser. Das
heisst, ich muss beim Sichern ein paar Sekunden laenger warten. Etc.
2) Hier wurde der Verdacht geaeussert, den auch ich habe:
Firbird (2.1. und 1.5) hat einen Bug, wenn im Subselect "Find First n"
verwendet wird. Auch mit diesem schlage ich mich nicht mehr herum, wenn
ich das Problem erschlage. Feige, von hinten erschlage, ich gebe es zu.
Doch Hauptsache, es ist mal tot ;-)
=============================================================
Das ist die Basismenge per SQL abgefragt.
Die Abfrage ist OHNE Subselect blitzschnell.
(Sie wuerde aber mit Zugriff auf etwa comm im Subselect extrem langsam.
Dieses Comm scheint den join rueckabzuwickeln und produziert Millionen
von Zugriffen.)
Hier die schnelle:
s := 'select tbkurszeilen.fk_kontrakt as fk_kontrakt,' +
' tbkontrakte.name_ as name_,' +
' tbkontrakte.comm as comm,' +
' tbkurszeilen.fk_jdatum as fk_jdatum,' +
' tbkurszeilen.o as o,' +
' tbkurszeilen.h as h,' +
' tbkurszeilen.l as l,' +
' tbkurszeilen.c as c,' +
' tbkurszeilen.volume as volume,' +
' tbkurszeilen.openinterest as openinterest,' +
' tbkurszeilen.id_kurszeilen as id_kurszeilen,' +
' tbkurszeilen.trflag as Tradeflag' +
' from tbkurszeilen' +
' JOIN' +
' tbkontrakte on tbkurszeilen.fk_kontrakt =
tbkontrakte.id_kontrakt' +
' and tbkurszeilen.fk_jdatum = ' + QuotedStr(EIN_DATUM) +
' order by comm asc, openinterest desc;';
=======================================================================
So sieht sie ein Abfrageergebnis aus
(oups, ich hole ein paar Spalten raus, sonst bricht die Zeile um und es
wird unlesbar):
FK_KONTRAKT NAME_ COMM DATUM OPENINTEREST FK_TRADE ID_KURSZEILEN
9 ADH9 AD 15.01.2009 43100 5389569
8 ADM9 AD 15.01.2009 195 5389135
7 ADU9 AD 15.01.2009 153 5388716
127 BOH9 BO 15.01.2009 110591 5421170
126 BOK9 BO 15.01.2009 31438 5420779
125 BON9 BO 15.01.2009 27541 5420408
124 BOQ9 BO 15.01.2009 5777 5419928
122 BOV9 BO 15.01.2009 4166 5419152
123 BOU9 BO 15.01.2009 4145 5419551
591 BPH9 BP 15.01.2009 77632 5555000
590 BPM9 BP 15.01.2009 2573 5554642
589 BPU9 BP 15.01.2009 8 5554254
759 CH9 C 15.01.2009 336105 5597184
757 CN9 C 15.01.2009 127703 5596193
758 CK9 C 15.01.2009 112830 5596644
756 CU9 C 15.01.2009 32285 5595419
1073 CCH9 CC 15.01.2009 47045 5697131
1072 CCK9 CC 15.01.2009 31012 5696687
1071 CCN9 CC 15.01.2009 14286 5696265
1070 CCU9 CC 15.01.2009 7998 5695840
1299 CDH9 CD 15.01.2009 58319 5786183
1298 CDM9 CD 15.01.2009 2370 5785750
1297 CDU9 CD 15.01.2009 1250 5785329
1510 CLH9 CL 15.01.2009 382302 5870134
1507 CLM9 CL 15.01.2009 115975 5868804
1509 CLJ9 CL 15.01.2009 93297 5869589
1511 CLG9 CL 15.01.2009 61455 5870673
1508 CLK9 CL 15.01.2009 54640 5869101
1506 CLN9 CL 15.01.2009 52254 5868010
1505 CLQ9 CL 15.01.2009 27589 5867492
1504 CLU9 CL 15.01.2009 21408 5867130
1503 CLV9 CL 15.01.2009 21000 5866568
1502 CLX9 CL 15.01.2009 17542 5865986
1836 CTH9 CT 15.01.2009 69003 6008580
1835 CTK9 CT 15.01.2009 22724 6008069
1834 CTN9 CT 15.01.2009 19306 6007608
1833 CTV9 CT 15.01.2009 285 6007069
2142 CUH9 CU 15.01.2009 126198 6113378
2141 CUM9 CU 15.01.2009 1369 6112956
usw.
=======================================================
so SOLL es aussehen.
Von jedem Ding sollen genau jene max drei gewaehlt werden, die den
hoechsten openinterest Wert haben, also so:
FK_KONTRAKT NAME_ COMM DATUM OPENINTEREST ID_KURSZEILEN
9 ADH9 AD 15.01.2009 43100 5389569
8 ADM9 AD 15.01.2009 195 5389135
7 ADU9 AD 15.01.2009 153 5388716
127 BOH9 BO 15.01.2009 110591 5421170
126 BOK9 BO 15.01.2009 31438 5420779
125 BON9 BO 15.01.2009 27541 5420408
591 BPH9 BP 15.01.2009 77632 5555000
590 BPM9 BP 15.01.2009 2573 5554642
589 BPU9 BP 15.01.2009 8 5554254
759 CH9 C 15.01.2009 336105 5597184
757 CN9 C 15.01.2009 127703 5596193
758 CK9 C 15.01.2009 112830 5596644
1073 CCH9 CC 15.01.2009 47045 5697131
1072 CCK9 CC 15.01.2009 31012 5696687
1071 CCN9 CC 15.01.2009 14286 5696265
usw.
==================================================================
der Aufbau der Tabellen ist dieser:
Jeden Tag gibt es bestimmte Werte inklusive dem Wert "open interest".
Also z.B.
15.9.2009 .....oi=104735;
16.9.2009 ..... 124735...
17.9.2009 ..... 14735----
Wir wollen hier EINEN Tag ueber ALLE Werte betrachten.
WOHIN gehoert jetzt dieser Satz mit taeglichen Daten:
Dazu gibt es einen FK in jeder Tagezeile.
Dieser FK zeigt auf die Eckdaten der jeweiligen Kursreihe, wie
Rohstoff, Liefermonat, uam.
Das heisst, wir nehmen den Wert openinterest aus der Tabelle mit den
taeglichen Daten und die Informatione zu WELCHER Gruppe ein Datensatz
gehoert ueber den Fremdschluessel aus einer anderen Tabelle.
Raetselloeser: Bitte besonders Augenmerk auf den Join und das Fakt,
dass wir hier ZWEI Tabellennamen abfragen: tbkurszeilen und
tbkontrakte. Viele Zugriffe auf tbkurszeilen bremsen die Sache aus.
Also etwa comm im Subselect nach dem join ist nicht mehr akzeptabel vom
Tempo her.
Wie das dann gehen soll? - Ich habe keine Ahnung.
Darum filtere ich die Query schaebig via Delphi.
Nicole