Discussion:
Neuposting: Die Provokation
(zu alt für eine Antwort)
Nicole Wagner
2011-03-02 10:33:56 UTC
Permalink
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
Joe Galinke
2011-03-02 11:47:29 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
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;';
Du bist nach wie vor nicht bereit, mal das komplette Statement mit
Subselect und First zu posten? Also das zwar langsame, aber dafür ohne
Filterevent arbeitende?
Auch nicht, wenn ich ganz lieb "Bitte" sage?

Die letzten die ich von dir sah waren ja auch nach Thomas und meiner
Empfehlung immer noch nicht korrekt. Ob meine Korrekturen überhaupt
ausprobiert wurden weiß ich ja nicht.


Gruß, Joe
--
Nicole Wagner
2011-03-02 12:56:18 UTC
Permalink
Post by Joe Galinke
Hallo Nicole,
Post by Nicole Wagner
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;';
Du bist nach wie vor nicht bereit, mal das komplette Statement mit
Subselect und First zu posten? Also das zwar langsame, aber dafür ohne
Filterevent arbeitende?
Auch nicht, wenn ich ganz lieb "Bitte" sage?
Die letzten die ich von dir sah waren ja auch nach Thomas und meiner
Empfehlung immer noch nicht korrekt. Ob meine Korrekturen überhaupt
ausprobiert wurden weiß ich ja nicht.
Gruß, Joe
Ich habe gerade noch mal nachgesehen.
In gewisser Weise gibt es das nicht. Ich habe nur einen Sauhaufen von
Zwischen-Backups mit jeder Menge auskommentierter Zeilen von
Fehlerversuchen drinnen. Die wenigen lesbaren Versionen davon habe ich
alle gepostet. Mehr habe ich nicht.

Das Filterelement hat NIE gearbeitet.
Ergo gibt es auch keine "schoene" Version.

Ich habe alles von Dir gedruckt und ALLES ausprobiert. Wort fuer Wort.
Es gab nur zahllose Versionen ueber eine halbe Seite, die gemeinsam
hatten: "rattert 15 Minuten und rechnet falsch". Die habe ich nicht
gespeichert. Ein falscher Klick und ich sitze wieder eine Viertelstunde
wie ein Trottel herum und kann nicht weiterarbeiten. Sowas speichert
man lieber nicht.

Ich habe es nicht zusammengebracht, dass das First im Subselect je
etwas eingeschraenkt haette via First. Und hier scheint mir auch das
Problem zu liegen.

Ich denke, es liegt nicht an Dir oder Thomas, sondern an Firebird.

Wenn ich eine vorgeschlagene Veraenderung nicht probiert habe, dann lag
es daran, dass die Syntax nicht akzeptiert wurde:
Dass mit den Alias' geht nur jeweils innerhalb der einzelnen Bloecke.
D.h. auch der zweite Block akzeptiert wieder nur seinen eigenen(!)
Alias. Weshalb viel von Euren Vorschlaegen von Anfang an nicht ging.
Was syntaktisch ging, ist gepostet.


Nicole
Joe Galinke
2011-03-02 13:48:16 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Ich habe es nicht zusammengebracht, dass das First im Subselect je
etwas eingeschraenkt haette via First. Und hier scheint mir auch das
Problem zu liegen.
Ich denke, es liegt nicht an Dir oder Thomas, sondern an Firebird.
Ich lehne mich sonst ungern aus dem Fenster, hier wage ich es.

Ich vermute, es lag wirklich an Dir. Ich weiß ganz sicher, dass einige der
von Dir hier gezeigten Empfehlungsumsetzungen falsch waren. Falsch im
Hinblick auf die Aliasverwendeung. Das habe ich auch an mehr als einer
Stelle beschrieben und korrigiert, aber Du hast die Korrekturen entweder
nicht oder fehlerhaft umgesetzt.
Damit meine ich jetzt nicht die Laufzeit, nur und ausschließlich das
Ergebnis.

Aber selbst bei der Laufzeit bin ich bereit zu wetten, dass man sehr viel
hätte herausholen können.
Post by Nicole Wagner
Wenn ich eine vorgeschlagene Veraenderung nicht probiert habe, dann lag
Dass mit den Alias' geht nur jeweils innerhalb der einzelnen Bloecke.
D.h. auch der zweite Block akzeptiert wieder nur seinen eigenen(!)
Alias. Weshalb viel von Euren Vorschlaegen von Anfang an nicht ging.
Was syntaktisch ging, ist gepostet.
Läuft dieses Statement bei Dir?
Ja, da fehlen Spalten, aber die spielten für die Problemlösung keine Rolle
und schadeten beim Lesen der Übersicht.

select tbkurszeilen.fk_kontrakt as fkkontrakt,
KON_MAIN.NAME_ as name_,
fk_jdatum as datum,
tbkurszeilen.openinterest as openinterest,
KON_MAIN.comm as comm_

from tbkurszeilen
join tbkontrakte KON_MAIN ON
tbkurszeilen.fk_kontrakt=KON_MAIN.ID_KONTRAKT


where KON_MAIN.id_kontrakt in
(select first 3 KON_SUB.id_kontrakt from tbkontrakte KON_SUB

LEFT JOIN tbkurszeilen KURSZ_SUB ON
(KURSZ_SUB.fK_kontrakt=KON_SUB.id_kontrakt)
WHERE KON_SUB.comm=KON_MAIN.comm
ORDER BY KURSZ_SUB.openinterest DESC)

ORDER BY KON_MAIN.COMM, tbkurszeilen.openinterest DESC




Gruß, Joe
--

Loading...