Monatssplitting (SQL Server 2000)

25/10/2007 - 23:45 von Alexander Bierig | Report spam
Tag,

ich habe da mal wieder eine kleinere Frage, wobei viel zu lesen vorangeht.

Wir haben eine Mitgleidschaftstabelle unserer Kunden, welche wir gerne mit
unseren Ausgaben verbinden würden.

Die Tabelle leifert uns dei Mitgliedschaftszeiten in Jahreswerten je Daten
Satz (also Bsp vom 12.02.07 bis 31.12.07)


Wir haben für unsere Würfel eine Dimensionstabelle (dim_zeit) welche eine
id_datum (int) führt als Bsp: 20071025
datum (datetime) 25.10.2007
monat (char(2)) 10
monats_name (varchar(50)) Oktober
und doch dei Wochen/Tages/Quartalsattribute.
Die Dimension làuft recht weit (11.000 Tage)

Das Problem nun ist, dass ich in der Mitgliedschaftstabelle
"vorrausschauende" Werte habe; ein bis-datum vom 31.12.07, wàhrend die
Finanzler erst im Oktober sind.

Also ist der Ansatz die "Jahreszeilen" durch ihre entsprechenden
Monatszeilen zu ersetzen;

Bsp:

von:09.02.2007; bis:31.12.2007; tage:326
soll zerfallen in
von:09.02.2007; bis:28.02.2007; tage:20
von:01.03.2007; bis;31.02.2007; tage:31

von:01.12.2007; bis:31.12.2007; tage: 31

das u.a. stehende Statement macht genau das.
Damit der kann der Würfel nachher einiges neben dem recht wichtigem
Vergleich Soll/Ist je Monat anzeigen.

Und NUN das grosse ABER:

gejoined werden 3,6 Mio Datensàtze mit den o.a. 11tsd, dabei ist die
Partitionierungsmöglichkeit aufs Jahr mit 4 Jahren.
Das Monatssplitting bringt eine geschàtzte Ver-Elf-Fachung der Datensàtze.

Ich habe in Folge also neben extremer Laufzeit einen irrenPlatzverbrauch in
der Tempdb, selbst wenn ich nur ein Jahr in den Quelldaten aufnehme, der DBA
kam heute schon um die Ecke geflitzt, ob wir des Wahnsinss kesse Beute seien
8-))

Daher die Frage,

wo seht Ihr noch eine Optimierungsmöglichkeit? Auch im Ansatz, wie man
Indexe setzen sollte dafür.



select
sv.id_datum_von, sv.id_datum_bis, sv.versich_tage
, zt.jahr, zt.monat_name, zt.monat
, case
when min(zt.id_datum)< sv.id_datum_von then sv.id_datum_von
else min(zt.id_datum)
end exakt_id_stdat
, case
when max(zt.id_datum)>sv.id_datum_bis then sv.id_datum_bis
else max(zt.id_datum)
end exakt_id_enddat
, datediff
(dd
, convert(datetime,convert(varchar,
case
when min(zt.id_datum)< sv.id_datum_von then sv.id_datum_von
else min(zt.id_datum)
end))
, convert(datetime,convert(varchar,
case
when max(zt.id_datum)>sv.id_datum_bis then sv.id_datum_bis
else max(zt.id_datum)
end)) +1
) verstage_monat

from dbo.sa40_verstage_help sv
inner join dwh..dim_zeit zt on zt.datum between datum_von and datum_bis
group by sv.id_datum_von, sv.id_datum_bis, sv.versich_tage , zt.jahr,
zt.monat_name, zt.monat


Das Laufzeiutproblem liegt nicht an den vielen Konvertierungen ind e
rTagesberechnung, auch wenn ich diese weglasse udn alles erst mal in eine
TempTable schreiben will und dann berechnen, làuft es über Stunden
(ich lasse es heute nach in Abstimmugn mit dem DBA auf einem Testsystem
durchlaufen)

Vielen Dank fürs geduldige Lesen

MfG

Alex.


Wegen der Berge von Spam:
die Emailadresse lautet
alexander.at.taxi.minus.stuttgart.dot.de

Schon Mitglied bei www.sqlpass.de?
 

Lesen sie die antworten

#1 Berthold Neumann
28/10/2007 - 10:14 | Warnen spam
Hallo Alexander,

deine Fragestellung betrifft sehr grundsàtzliche Themen der
multidimensionalen Datenmodellierung.
Diese lassen sich nicht so ganz einfach über eine Newsgroup beantworten
bzw. lösen.

Zuerst muss geklàrt bzw. festgelegt werden, was die Finanzler denn
tatsàchlich im Würfel sehen wollen.
Was für Werte (Soll/Ist) sollen gegenübergestellt werden?

Finanzler interessieren sich meist für Monatswerte.
Also mach eine Faktentabelle-Soll auf Monatsebene:
- Monat (200709)
- Kunde (12345)
- Sollwert

Analog dazu erstellt Du eine Faktentabelle-Ist.

Die Dimension legst du neu an:
- Monat (200709)
- Jahr (2007)

Damit ist der eigentliche multidimensionale Bereich dann recht einfach.

Was jetzt noch bleibt, ist die Frage, wie du an die Faktentabellen kommst.
Das hàngt primàr von den Ausgangstabellen und der Spezifikation der
Finanzler ab.

Grundsàtzlich würde ich an deinem SQL-Statement folgendes àndern:

- between beim inner join vermeiden. Nach meiner Erfahrung ist eine
direkte Zuordnung (=) erheblich schneller. Auch wenn du dafür eine Tabelle
mit 11.000 Tagessàtzen anlegen musst.
- arbeite wenn möglich mit temporàren Zwischentabellen, das erleichtert
die Analyse erbeblich


Gruß

Berthold







Am 25.10.2007, 23:45 Uhr, schrieb Alexander Bierig
:

Tag,

ich habe da mal wieder eine kleinere Frage, wobei viel zu lesen
vorangeht.

Wir haben eine Mitgleidschaftstabelle unserer Kunden, welche wir gerne
mit
unseren Ausgaben verbinden würden.

Die Tabelle leifert uns dei Mitgliedschaftszeiten in Jahreswerten je
Daten
Satz (also Bsp vom 12.02.07 bis 31.12.07)


Wir haben für unsere Würfel eine Dimensionstabelle (dim_zeit) welche eine
id_datum (int) führt als Bsp: 20071025
datum (datetime) 25.10.2007
monat (char(2)) 10
monats_name (varchar(50)) Oktober
und doch dei Wochen/Tages/Quartalsattribute.
Die Dimension làuft recht weit (11.000 Tage)

Das Problem nun ist, dass ich in der Mitgliedschaftstabelle
"vorrausschauende" Werte habe; ein bis-datum vom 31.12.07, wàhrend die
Finanzler erst im Oktober sind.

Also ist der Ansatz die "Jahreszeilen" durch ihre entsprechenden
Monatszeilen zu ersetzen;

Bsp:

von:09.02.2007; bis:31.12.2007; tage:326
soll zerfallen in
von:09.02.2007; bis:28.02.2007; tage:20
von:01.03.2007; bis;31.02.2007; tage:31

von:01.12.2007; bis:31.12.2007; tage: 31

das u.a. stehende Statement macht genau das.
Damit der kann der Würfel nachher einiges neben dem recht wichtigem
Vergleich Soll/Ist je Monat anzeigen.

Und NUN das grosse ABER:

gejoined werden 3,6 Mio Datensàtze mit den o.a. 11tsd, dabei ist die
Partitionierungsmöglichkeit aufs Jahr mit 4 Jahren.
Das Monatssplitting bringt eine geschàtzte Ver-Elf-Fachung der
Datensàtze.

Ich habe in Folge also neben extremer Laufzeit einen irrenPlatzverbrauch
in
der Tempdb, selbst wenn ich nur ein Jahr in den Quelldaten aufnehme, der
DBA
kam heute schon um die Ecke geflitzt, ob wir des Wahnsinss kesse Beute
seien
8-))

Daher die Frage,

wo seht Ihr noch eine Optimierungsmöglichkeit? Auch im Ansatz, wie man
Indexe setzen sollte dafür.



select
sv.id_datum_von, sv.id_datum_bis, sv.versich_tage
, zt.jahr, zt.monat_name, zt.monat
, case
when min(zt.id_datum)< sv.id_datum_von then sv.id_datum_von
else min(zt.id_datum)
end exakt_id_stdat
, case
when max(zt.id_datum)>sv.id_datum_bis then sv.id_datum_bis
else max(zt.id_datum)
end exakt_id_enddat
, datediff
(dd
, convert(datetime,convert(varchar,
case
when min(zt.id_datum)< sv.id_datum_von then
sv.id_datum_von
else min(zt.id_datum)
end))
, convert(datetime,convert(varchar,
case
when max(zt.id_datum)>sv.id_datum_bis then
sv.id_datum_bis
else max(zt.id_datum)
end)) +1
) verstage_monat

from dbo.sa40_verstage_help sv
inner join dwh..dim_zeit zt on zt.datum between datum_von and datum_bis
group by sv.id_datum_von, sv.id_datum_bis, sv.versich_tage , zt.jahr,
zt.monat_name, zt.monat


Das Laufzeiutproblem liegt nicht an den vielen Konvertierungen ind e
rTagesberechnung, auch wenn ich diese weglasse udn alles erst mal in eine
TempTable schreiben will und dann berechnen, làuft es über Stunden
(ich lasse es heute nach in Abstimmugn mit dem DBA auf einem Testsystem
durchlaufen)

Vielen Dank fürs geduldige Lesen

MfG

Alex.







Berthold Neumann
http://www.sql-ssis.de
Ich unterstütze PASS Deutschland e.V. (http://www.sqlpass.de)

Ähnliche fragen