Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Procedure füllt tempdb bis zur Plattenkapazitätsgrenze - drückt etwas

225 views
Skip to first unread message

Alexander Bierig

unread,
Oct 29, 2003, 4:37:14 AM10/29/03
to
Guten Tag,

unsere Entwicklungsumgebung ist: W2K SP 3 (Server und Workstation) mit
SQL-Server 7 SP 3
Visual Studio 6 Enterprise Datenverbindung per ADO

Den SQL-Server in der Version 7 haben wir aufgesetzt, da unser Kunde sagte
er kriegt nur nen SQL-Server 7.

Die Zielplattform ist nun W2K Server advanced Englisch und SQL-Server 2000
SP1 englisch. 3Gig Ram, 2,5 Gig dem SQL-Server zugewiesen: Er holt sich aber
nur 2 Gig
Aufgrund der Sicherheitsgedanken des Kunden wird die Maschine von dessen
Netzadmins installiert, gewartet und verwaltet. Wir können nur mit unserer
Software und dem EM und ISQL über Clientmaschinen drauf zugreifen.Und auf
den Server eingeschränkt per Remotesoftware


Wir haben letztendlich drei Gruppen von stored Procedures, welche die
Datenbank abfragen.

Allen gemeinsam sind die Bedingungen in den Abfragen

Auf unsere Entwicklungsumgebung laufen die Abfragen so im Schnitt 20 Minuten
und sie benutzen die TEMPDB nicht. Jedenfalls erscheint in Explorer keine
Änderung der Dateigrösse oder ihres Zugriffsdatums.

Der Server kämpfte ab Aufstellungstag mit nem Virus (w32.Welchia), der ist
jetzt von den Netzadmins erfolgreich verjagt (seit Sonntag)
Als wir mit der Datenbank auf den Zielserver umzogen gab's massive Probleme
(ich hatte hier angefragt) und nach einem erneuten Aufsetzen der Datenbank
lief die Datenbank, auch die Abfragen liefen
Die letzte erfolgreiche war am 17.Oktober

Über die Netzwerkgüte gab's ab und zu Timeoutprobleme -sonst fiel nichts
weiter auf.

Seit rd 10 Tagen fällt unser Abfragemodul aber regelmässig auf die Nase, da
zwei der drei Abfragebereiche über Gebühr lange laufen (ADO-Timeout 4.800
Sek)
Die Fehlermeldung des Servers kam allerdings nicht zurück vom SQL-Server.

Letztendlich brachten mich Einträge im Eventlog auf die Spur :vom
System:Platte beinahe voll, schaffen Sie Platz und eine weitere vom
SQL-Server: Keine Seiten mehr zu Allokieren in Tempdb -Platz schaffen.

Ich habe es daraufhin live beobachtet:
Die Datenbank hat derzeit 75 Gig, davon sind 5 frei
Im QueryAnalyze die fragliche Procedure aufgerufen kann man zuschauen wie
die TEMPDB wächst.
Nach 53 Gig ist dann die Platte voll und die Abfrage wird abgebrochen.
Der Queryanalyser hat dann die Fehlermeldung (Tempdb voll, und Vorschlag wie
man Platz kriegt)
Interessanterweise kann der SQL-Server dann immer noch Abfragen ausführen,
welche NICHT in die TEMPDB schreiben.

Unser Programm ruft die Proceduren auf dem Server per ADO auf
die erste Abfrage versagt und läuft an dieWand (Tempdb bis Anschlag
vollgemacht)
die zweite Abfrage führt direkt im Anschluss zum Ergebniss
die dritte wiederum versagt und fährt an dieWand.

unser Logauszug

13:14:13 -> Aktive Datenbak auf SQL-Serverist 'G'
13:14:15 -> Microsoft Excel gestartet.
13:14:17 -> Vorbereitungen für Abfragen abgeschlossen
13:14:17 -> Abfrage auf Gesamtsumme für das Jahr 2003
13:14:17 -> Procedure-Aufruf: sumbrteam_jahr, 2003
14:34:23 -> VB-Fehlernummer-> 0
14:34:23 -> VB-Fehlertext->
14:34:23 -> VB-Fehlermodul->
14:34:23 -> +++++++++++++++++++++++++++++++++++++++
14:34:24 -> In den Abfragen trat ein Fehler auf - die Ergebnisse werden
verworfen.
14:34:24 -> Das Excel Objekt geschlossen und die Datendatei 'summen2003 -
27-10-2003.xls' gelöscht.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++
27.10.03 -> Beginn Auswertungen Gesamtbeanstandungen je SSL/Team/Monat
14:34:24 -> Beginn Verbindungsaufbau zu Server SQL-Srever
14:34:24 -> Verbindung zu Server 'SQL-Server hergestellt.
14:34:24 -> Vorbereitungen für Abfragen abgeschlossen
14:34:24 -> Aktive Datenbank auf SQL-Server ist: 'G'
14:34:25 -> Microsoft Excel gestartet.
14:34:26 -> Abfrage Gesamtbeanstandungen für das Jahr 2003
14:34:26 -> Procedure-Aufruf: gesamtbeanstandung_br_jahr, 2003
15:03:37 -> Excel-Tabelle 'akt. Jahr' beschrieben, Anzeigefelder
beschrieben.

Anfangs ging ich von einem neuen Bug in unserem Programm aus...und habe
daher an falscher Stelle gesucht.

Jetzt kristallisiert sich der SQL-Server als der Übeltäter raus.

Nur, wieso änderte der SQL-Server sein Verhalten so erstaunlich und wo kann
ich ansetzen, dieses Problem zu lösen?
Ich muss allerdings anmerken, dass wir NIE darauf geachtet hatten, ob auf
unserem Kundenserver eine Procedure IN die TEMPDB schreibt oder nicht.
Es gab allerdings bis zum 17. Okt auch keine Probleme (Ausser dem Bugfixing
unseres Programms).

Nun sollte der SQL-Server des Kunden in den alleinigen Betrieb gehen und
die Entwicklungsumgebung (welche die noch Echtdaten parallel mitführt) für
anderes verwendet werden.

Daher bitte ich um Hilfe.


Mit freundlichen Grüssen

Alex.


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


Elmar Boye

unread,
Oct 29, 2003, 4:52:43 AM10/29/03
to
Hallo Alexander,

Alexander Bierig <dusollstk...@verschicken.de> schrieb ...


> Guten Tag,
>
> unsere Entwicklungsumgebung ist: W2K SP 3 (Server und Workstation) mit
> SQL-Server 7 SP 3
> Visual Studio 6 Enterprise Datenverbindung per ADO
>

[traurige Geschichte gesnippt]

> unser Logauszug
>

[ gesnippt, kann man als Aussenstehender nichts mit anfangen]

>
> Jetzt kristallisiert sich der SQL-Server als der Übeltäter raus.

Glaube ich aber auch nicht.

>
> Nur, wieso änderte der SQL-Server sein Verhalten so erstaunlich und
> wo kann ich ansetzen, dieses Problem zu lösen?

Erzähle uns mal eher was über Deine Prozedur(en).
Sonst sehe ich da keine Möglichkeit - ausser Dich zu bedauern ;-)

Gruss
Elmar

Andreas Schmidt

unread,
Oct 29, 2003, 5:04:22 AM10/29/03
to

"Alexander Bierig" <dusollstk...@verschicken.de> schrieb im
Newsbeitrag news:bno1ob$a9v$00$1...@news.t-online.com...

> Ich habe es daraufhin live beobachtet:
> Die Datenbank hat derzeit 75 Gig, davon sind 5 frei

Riesige Datenbank, die üblichen Verdächtigen:

Wahrscheinlich laufen deine Datenbank(en) im Wiederherstellungsmodell
"Vollständig".

Du solltest die betreffenden Datenbank(en) auf "Einfach" umstellen,
da du wohl kein Backup des Transactionlog Files durchführst.

Danach alle Datenbanken im EM verkleinern.

Andreas


--
Database Explorer for ADO (Freeware)
http://mitglied.lycos.de/ajs/adodeskexe.zip

Alexander Bierig

unread,
Oct 29, 2003, 5:54:04 AM10/29/03
to
Grüss Dich Andreas,


> Riesige Datenbank, die üblichen Verdächtigen:

8-))


> Wahrscheinlich laufen deine Datenbank(en) im Wiederherstellungsmodell
> "Vollständig".
>
> Du solltest die betreffenden Datenbank(en) auf "Einfach" umstellen,
> da du wohl kein Backup des Transactionlog Files durchführst.

Das Wiederherstellungsmodell ist "Massenkopieren/Bulkinsert"

Ist nötig gewesen aufgrund Fehlermeldungen für das Einlesen mittles BCP


Gruss

Alex.


Frank Matthiesen

unread,
Oct 29, 2003, 6:07:50 AM10/29/03
to
Alexander Bierig wrote:
>
> Das Wiederherstellungsmodell ist "Massenkopieren/Bulkinsert"
>
> Ist nötig gewesen aufgrund Fehlermeldungen für das Einlesen mittles
> BCP

Ihr lest also regelmässig csv-Files per BCP ein?
Warum nicht per DTS und dort entsprechend auf Fehlimporte reagieren?
Dann reicht auch ein einfaches Wiederherstellungsmodell

gruss

frank


Jürgen Beck

unread,
Oct 29, 2003, 6:12:32 AM10/29/03
to

Hallo Frank,

Nein, reicht es nicht!

Bei einem einfachen Wiederherstelungsmodell ist es _nicht_ möglich,
Sicherungen einzuspielen, um bis zu einem bestimmten Zeitpunkt
wiederherzustellen.

Beim Massenkopieren/Bulkinsert ist es zumindest möglich,
Transaktionsprotokollsicherungen durchzuführen und diese wiederherzustellen
(auch wenn man keine Uhrzeit eingeben kann).

--
Jürgen Beck
MCSD.NET, MCDBA, MCT
www.Juergen-Beck.de


Frank Matthiesen

unread,
Oct 29, 2003, 6:51:42 AM10/29/03
to
Jürgen Beck wrote:

> Nein, reicht es nicht!

Hallo Jürgen,

das ist mir schon klar. Ich ging aber davon aus, dass Alexander die
massenprotokollierte Wiederherstellung gewählt hat, weil er sonst nicht auf
Fehler beim Import per BCP reagieren kann!?

Gruss

Frank


Jürgen Beck

unread,
Oct 29, 2003, 7:05:21 AM10/29/03
to

Hallo Frank,

dann schreibe Deine Annahme beim nächsten Mal hinein, sonst kann das durch
einen nicht so technisch versierten anderen Leser sehr einfach missverstnden
werden.

:-)

Elmar Boye

unread,
Oct 29, 2003, 10:44:32 AM10/29/03
to
Hallo Andreas, Frank, Jürgen und Frank,

Jürgen Beck <nospam2N...@Juergen-Beck.de> schrieb ...


> Frank Matthiesen wrote:
>> Jürgen Beck wrote:
>>
>>> Nein, reicht es nicht!
>>

>> das ist mir schon klar. Ich ging aber davon aus, dass Alexander die
>> massenprotokollierte Wiederherstellung gewählt hat, weil er sonst
>> nicht auf Fehler beim Import per BCP reagieren kann!?
>

> dann schreibe Deine Annahme beim nächsten Mal hinein, sonst kann das
> durch einen nicht so technisch versierten anderen Leser sehr einfach
> missverstnden werden.

Auch wenn das Protokoll ganz wichtig ist, denke ich kaum dass
das die Ursache der Probleme ist oder sein kann.
So ganz nebenbei: massenprotokolliert gibts beim SQL Server 7 noch nicht.
Und bei gesetzter BULK COPY Option ist eine Vollsicherung oder differentielle
Sicherung sowieso notwendig, wenn ein massenprotokollierter Befehl
stattgefunden hat, da das Protokoll ungültig wird. Und für tempdb
gilt ohnehin immer einfache Wiederherstellung (in SQL Server 2000
Terminus)

Richtung Frank - falls er mich denn noch liest:
Da die tempdb überläuft, gibts dafür massig Gründe wie Cursor (Server wie
von serverseitige der Anwendung), Sortier-, Hashoperationen usw., die
jedoch ohne Kenntnis der Prozedur bestenfalls geraten werden können.

Gruss
Elmar

Andreas Schmidt

unread,
Oct 29, 2003, 11:21:29 AM10/29/03
to

"Alexander Bierig" <dusollstk...@verschicken.de> schrieb im
Newsbeitrag news:bno68d$jk$04$1...@news.t-online.com...


> > Wahrscheinlich laufen deine Datenbank(en) im Wiederherstellungsmodell
> > "Vollständig".
> >
> > Du solltest die betreffenden Datenbank(en) auf "Einfach" umstellen,
> > da du wohl kein Backup des Transactionlog Files durchführst.
>
> Das Wiederherstellungsmodell ist "Massenkopieren/Bulkinsert"
>
> Ist nötig gewesen aufgrund Fehlermeldungen für das Einlesen mittles BCP

BCP sollte auch im Widerherstellungsmodell "Einfach" laufen.

Falls du das Wiederherstellungsmodell "Massenkopieren/Bulkinsert"
verwendest, dann *musst* du auch regelmässig ein Backup fahren
und dabei das Transactionlogfile sichern.
Falls du dies nicht tust, wird dein Transactionlogfile immer grösser
werden.

Andreas

Alexander Bierig

unread,
Oct 29, 2003, 4:06:33 PM10/29/03
to
Grüss Dich Frank,


> das ist mir schon klar. Ich ging aber davon aus, dass Alexander die
> massenprotokollierte Wiederherstellung gewählt hat, weil er sonst nicht
auf
> Fehler beim Import per BCP reagieren kann!?

Das ist richtig so.

Der Server steht jetzt auf einfacher Wiederherstellung

Problem nicht gefixed.

Gruss

Alex.


Alexander Bierig

unread,
Oct 29, 2003, 5:00:33 PM10/29/03
to
Grüss Dich Elmar,

> Erzähle uns mal eher was über Deine Prozedur(en).
> Sonst sehe ich da keine Möglichkeit - ausser Dich zu bedauern ;-)

8-))

Nochmals das Verhalten:

auf der Entwicklungsumgebung (SQL-Server 7 deutsch SP3) eine Datenbank
eingerichtet und ans Leben inkl Abfragen gebracht.

Diese mittels dem EM als Skript exportiert und dann die ganze DB auf dem
Kundenserver (SQL-Server 2000 englisch SP3) über das Script, einschliesslich
Indizes und Proceduren neu erstellt.

Per Massenkopieren die Echtdaten aus der Entwicklungsumgebung via CD in den
Kundenserver gelegt. Mit den Problemen, dass das BCP (aber stolz behauptete,
fertig zu sein) mittendrin 50 Mio Sätze unterschlug und der Server rd 60
Prozent der Usertabellen verlegte einschliesslich ALLER stored Procedures,
die nicht vom Server waren: also unsere.

Daraufhin Datenbank gelöscht und neu eingerichtet.

Daten nochmals per BCP eingelesen.

Nun stimmen die Daten überein.

Die Proceduren liefen wie erwartet und ich kam überhaupt nicht auf die Idee,
dass ein reines Select from in die Tempdb schreibt.

Das Sicherungskonzept auf diesem Rechner ist etwas mickrig: Da die Datenbank
ein Datengrab und keine Produktionsumgebung wie z.Bsp Lagerbuchhaltung ist
und nur Ergebnisse ausspucken soll, ist das mit der Sicherung nur bedingt
dringend: Mit dem fernen Provider beim Kunden vereinbart: Der SQL-Server
wird Samstags angehalten udn dann wird die ganze Maschine gesichert. Ein
Restor der DB bedeutet dann eben ein Restore der gesamten Maschine.
(Vorschlag von dem Provider des Kunden)


Ich habe die u.a. Procedure jetzt gerade eben hier auf dem
Entwicklugnsserver laufen lassen: Sie hat die Tempdb in Ruhe gelassen.

Auf dem Kundenserver müllt dieselbe Procedure (ich habe den Code vom Kunden
mit auf unseren Entwicklungsserver genommen und die Codes sind bis zur
Leerstelle identisch) die Tempdb voll.

Per Telefon gab mir ein Freund aus dem Osten (Hallo Ralf) den Tip während
des Procedurelaufs mittels SP_LOCK nachzusehen, was wie oft gesperrt wird:
(wobei ich mich da überhaupt nicht auskenne und er diktierte was ich
abfragen soll)

Die Abfrage auf die Schnelle war:

insert l exec sp_lock
go
select db_name(sp2),object_name(sp3),sp5,sp7,sp8 from l
where sp1=7
go


Auf den Entwicklungsserver (SQL 7) krige ich so um die 45 Prozesse unter der
User ID (mit der der Queryanalyser grade unterwegs ist) dabei ein-zwei
Locks auf der TempDb ohne Objektname(NULL) und Typ der Sperrung DB und Art S
wie Shared (Spalten 2+3,5,7,8) mit dem Status GRANT

Auf dem Kundenserver (SQL 2000) kriege ich so um die 95 Prozesse unter der
User ID des Queryanalysers
Dabei allerdings taucht dann die Tempdb so um die dreimal auf
Dabei sind zweimal DB-Locks mit Art NULL und einmal Filelock mit Art U wie
Update udn dem Status GRANT


folgend die Procedure, die tückische:


ALTER procedure sumbrteam_jahr_dc
@imjahr smallint=2000
as
select distinct
g.baureihe as Baureihe,kps.pfteam_nr as [Pf-Team],kps.pfteam_benennung as
[PF-Benennung],sum(g.kostensumme) as KostenGesamt, sum(g.nebenkosten) as
[Nebenkosten],sum(g.lohnkosten) as [Kosten Lohn],
sum(g.materialkosten) as [Kosten Material],sum(g.mkz) as [Kosten
Material-NK],
sum(g.betreuungsleistg) as [Kosten Betreuung],bininjahr as Jahr

FROM gukasdaten as g
INNER JOIN ssl_pfteam on g.pf_ssl = ssl_pfteam.ssl_nr
INNER JOIN known_pfteams as kps ON kps.pfteam_nr = ssl_pfteam.pfteam_nr
inner join pfteam_sa_ein as pfsein ON kps.pfteam_nr = pfsein.pfteam_nr
INNER JOIN pfteam_sca ON kps.pfteam_nr = pfteam_sca.pfteam_nr AND g.sca_art
= pfteam_sca.sca
inner join pfteam_prod_datum as pprod on kps.pfteam_nr=pprod.pfteam_nr
inner JOIN pfteam_sa_aus as pfsaus ON kps.pfteam_nr = pfsaus.pfteam_nr
inner JOIN pfteam_karform as pkar ON kps.pfteam_nr = pkar.pfteam_nr AND
g.kar_form = pkar.kar_form
inner join gebietsliste as geb on geb.landcode_dc=g.gebiet
inner join pfteam_gebiet pfgeb on pfgeb.pfteam_nr=kps.pfteam_nr and
pfgeb.gebietsname_dc=geb.gebietsname_dc
inner JOIN pfteam_baureihe as pbr ON kps.pfteam_nr = pbr.pfteam_nr AND
g.baureihe = pbr.baureihe

where (g.bininjahr = @imjahr) AND (g.sca_typ <> 'M')
and g.sparte in ('00','01') and g.gar_obj in ('G','g') and g.tga = '0'
and g.pf_ssl not in ('99800','99930') and left(g.pf_ssl_bld,1)<>'9' and
g.istamg=0
and g.prod_datum between pprod.ab_prod_datum and pprod.bis_prod_datum
and g.fahrgestellnr not in
(
select saf.fahrgestellnr from sa_aktuellefins as saf
where saf.fahrgestellnr=g.fahrgestellnr
and saf.sa_code=pfsaus.sa_code and pfsaus.pfteam_nr=kps.pfteam_nr
)
and g.fahrgestellnr in
(
select saf.fahrgestellnr from sa_aktuellefins as saf
where saf.fahrgestellnr=g.fahrgestellnr
and saf.sa_code=pfsein.sa_code and pfsein.pfteam_nr=kps.pfteam_nr
)

group by g.bininjahr,g.baureihe,kps.pfteam_nr,kps.pfteam_benennung
having sum(g.kostensumme) >0
order by g.baureihe,kps.pfteam_nr


Dabei ist die etwas grössere Datei die gukasdaten mit rd 15 Mio Sätzen und
die nächste die sa_aktuellefins mit rd 5,5 Mio Sätzen. Die anderen haben
dann so zwischen 80 und 200.000 Sätzen
Die Procedure summiert Kosten auf Kostenstellen auf, sie muss diese Kosten
eindeutig zuordnen können, daher waren neben den vielen Joins die beiden
Subselects nötig.

Laufzeit der Procedure gerade eben 18:54 auf Dual PIII 1000Mhz 1GiG RAM
PC133 Platte 105 Gig (Raid 0 SCSI U160) bei DB-Grösse 83 Gig, davon 10,5 Gig
frei:
Laufzeit der Procedure bei letzem fehlerfreien Lauf (am 22.10) 6:17 auf dem
Kundenserver Dual XEON 2800 3GiG RAM PC2100 Platte 120 Gig (RAID 5 U320) bei
DB-Grösse 75 Gig, davon 4,5 Gig frei


Vielen Dank für Eure Mühen bei der Hilfe.

Gruss

Alex.


Frank Matthiesen

unread,
Oct 30, 2003, 2:27:02 AM10/30/03
to
Alexander Bierig wrote:
> Der Server steht jetzt auf einfacher Wiederherstellung
>
> Problem nicht gefixed.

Du meinst, die tempdb läuft immer noch voll?

Wieviel Datensätze importierst Du denn?
Ausserdem würde ich, wenn möglich, 'BULK INSERT' verwenden. Ist eh schneller
als BCP...

Gruss

Frank


Frank Matthiesen

unread,
Oct 30, 2003, 2:33:44 AM10/30/03
to
Elmar Boye wrote:
> Richtung Frank - falls er mich denn noch liest:

Gestern Abend gelesen, aber zu müde zum posten

> Da die tempdb überläuft, gibts dafür massig Gründe wie Cursor (Server
> wie von serverseitige der Anwendung), Sortier-, Hashoperationen usw.,
> die jedoch ohne Kenntnis der Prozedur bestenfalls geraten werden können.

ACK

So lang Alexander keinen Workflow rausrückt, ist alles Tipperei ohne
Kristallkugel.

Gruss

Frank


Alexander Bierig

unread,
Oct 30, 2003, 3:30:07 AM10/30/03
to
Grüss Dich Frank,

> >
> > Problem nicht gefixed.
>
> Du meinst, die tempdb läuft immer noch voll?
>
> Wieviel Datensätze importierst Du denn?
> Ausserdem würde ich, wenn möglich, 'BULK INSERT' verwenden. Ist eh
schneller
> als BCP...

zr. Zeit einmal pro Woche ca 150.000 aus Ascii ROhfile Nicht mit BCP, da
dieses Rohfile stark verstümmelt ankommt - das macht aber kein Problem

Die tempdb läuft voll infolge einem
Select distinct felder from...

ich habe die Procedure hier reingestellt - leider geht bei mir gerade mein
t-online-news server nimmer also muss ich auf umwegen kommen.


Gruss

Frank Matthiesen

unread,
Oct 30, 2003, 3:55:47 AM10/30/03
to
Alexander Bierig wrote:
> Die tempdb läuft voll infolge einem
> Select distinct felder from...

Also ich hab hier ähnliche Datenmengen/Abfragen, aber nicht Deine Probleme.

*Tipp ins Blaue*
Schon mal versucht, das Subselect (sind ja beide identisch) vorab in eine
User-Tabelle zu schieben und dann mit dem restlichen Statement zu
"verjoinen"?

Gruss

Frank

Alexander Bierig

unread,
Oct 30, 2003, 4:16:55 AM10/30/03
to
Grüss Dich Frank

Nein.

Der Hintergrund ist,
dass die "Eigenschaften" der Kostenstellen recht vielfältig und erst in
ihrer Kombination fast vollständig eindeutig werden...
Der erste Ansatz jede Kostenstelle eindeutig über ihre Eigenschaften zu
beschreiben führte in der Gesamtkombination zu mehreren Millionen Sätzen -
und da ist Datenpflege mehr als kritisch
Also habe ich die Hilfstabellen erstellt, welche die jeweilige Eigenschaft
absolut eindeutig einer Kostenstelle zu ordnet.
Daher die vielen Joins.

Es bleiben allerdings zwei Stellen, an welcehn trotz allem mehrere Sätze
zurück kommen können das sind die
Es gibt ein Schadensereignis, welche primar auf mehrere Kostenstellen
auflaufen könnte.
Leider liefert eine andere Hilfstabelel (die sa_aktuellefins) wenns dumm
läuft zwei Eigenschaften (also auch zwei Sätze) die dann im Join BEIDE
zurückkommen - für eine Kostenberechnun ist das etwas doof.

Anders: Wenn ich das Ergebniss der Subselects in eine Tabelle lege und ein
Join mache kriege ich ebenfalls zwei Sätze gejoined und genau das will ich
ja nicht.

Daher interssiert an dieser Stelle nur die Tatsache das das Subselect einen
Satz (bis mehrere Sätze) liefert.

Die Procedure verursacht ja (das ist beobachtbar) auch demendsprechend
Prozessorlast

Aber sie blieb (in der Entwicklungsumgebung bleibt sie imme noch) von der
Tempdb die Finger weg.

Frank Matthiesen

unread,
Oct 30, 2003, 4:33:29 AM10/30/03
to
Alexander Bierig wrote:
> Nein.
>
> Der Hintergrund ist,
> dass die "Eigenschaften" der Kostenstellen recht vielfältig und erst
> in ihrer Kombination fast vollständig eindeutig werden...

Frage am Rande:
Was ist das ganze eigentlich?
Auswertung von Schadensfällen bezogen auf Fahrzeug, Zeit und Kostenstelle?
Sollte man eher in eine OLAP-DB schieben (wenn Ihr das nicht schon macht)

> Aber sie blieb (in der Entwicklungsumgebung bleibt sie imme noch) von
> der Tempdb die Finger weg.

Welche Unterschiede gibt es denn zw. Prod und Entw- Server?
Auf den ersten Blick SP1 auf Prod und SP3 auf Entwicklung, oder?
Vielleicht solltet Ihr da mal ansetzen.

Gruss

Frank


Alexander Bierig

unread,
Oct 30, 2003, 4:39:19 AM10/30/03
to
Grüss Dich Frank,


> > Die tempdb läuft voll infolge einem
> > Select distinct felder from...
>
> Also ich hab hier ähnliche Datenmengen/Abfragen, aber nicht Deine
Probleme.
>


Das verhalten bei diesem Fehler ist ja doch eigenartig:

Die Procedure läuft an, verursacht die gewohnten Schwankungen in der
CPU-last udn wenn sie beginnt die Tempdb zu füllen reduziert sich die
CPU-Last dramatisch. Bis die Prozedure die Tempdb vollmüllt vergehen
durchaus vier-fünf Minuten ohne gravierendem Anstieg der CPU-Last.

Der Server (also die NT Maschine) wird etwas träge in Antwortzeiten Er ist
also doch ziemlich mit seiner Platte beschäftigt.


Die Pocedure im Queryanalyser gestartet, reagiert aber SOFORT auf die
Abbruchanforderung


Stellvertretend für alle die anderen Helfer hier an Dich:

Ich danke für die Hilfe.

Alexander Bierig

unread,
Oct 30, 2003, 5:58:21 AM10/30/03
to
Grüss Dich Frank,

> > Aber sie blieb (in der Entwicklungsumgebung bleibt sie imme noch) von
> > der Tempdb die Finger weg.
>
> Welche Unterschiede gibt es denn zw. Prod und Entw- Server?
> Auf den ersten Blick SP1 auf Prod und SP3 auf Entwicklung, oder?
> Vielleicht solltet Ihr da mal ansetzen.

Entwicklungsumgebung:
die hiesige Domäne
W2K Server SP3 deutsch
SQl 7 SP3 deutsch (Da Kunde ursprünglich sgte er kriegt nur SQL 7)


Kundenserver
W2K Server advanced SP4 english
SQL 2K SP3 englisch

Beidesmal Zugriff über Clients
Das Frontend zur Datenbearbeitung via VB und ADO
Der Queryanalyser/Em usw... auch nur per Client


Ich kann es nachweisen: Die Prozedure leif am 22.1003 auf dem Kundenserver
letzmalig fehlerfrei durch (Ich habe das Ergebniss und entsprechende
Logeinträge des Frontends)
Ich habe aber NIE überprüft, ob die Procedure auf dem Kundenteil in die
Tmpdb schreibt. Wozu auch.

Ich habe auch den SQL 2K im Verdacht, weis aber nicht wo ich da weiters
ansetzen soll.

Elmar Boye

unread,
Oct 30, 2003, 6:11:31 AM10/30/03
to

Hallo Alexander,

Alexander Bierig <dusollstk...@verschicken.de> schrieb ...

> Grüss Dich Elmar,
>

Einleitung von wegen Lesen in anderem Posting: Deine EMail
ist zwar angekommen, ich habe die aber erst heute gesehen.
Denn wegen Swen Müll rufe ich die Konten aber fast nie ab
oder lösche gleich...

>> Erzähle uns mal eher was über Deine Prozedur(en).
>

> auf der Entwicklungsumgebung (SQL-Server 7 deutsch SP3) eine Datenbank
> eingerichtet und ans Leben inkl Abfragen gebracht.
>
> Diese mittels dem EM als Skript exportiert und dann die ganze DB auf
> dem Kundenserver (SQL-Server 2000 englisch SP3) über das Script,
> einschliesslich Indizes und Proceduren neu erstellt.

Die Sache mit dem verspätete Pferdewechsel hatte ich gestern überlesen
(und war erst noch auf dem 7er Gaul).
Aber daraus ergeben sich doch ziemlich schwerwiegende Konsequenzen.
Denn der Optimierer vom SQL Server 2000 ist um einiges anders als
der vom 7er (in etwa Ackergaul zu Rennpferd) und jegliche Vergleiche
aus Tests sind somit nicht vergleichbar.

Damit Du zu einer vernünftigen Lösung kommst würde ich Dir als
erstes raten einen Upgrade auf SQL Server 2000 SP3 zu machen,
damit Du mit gleichen Massstab misst.

Damit da nicht zu viel Zeit bei drauf geht, würde ich die einen
Upgrade auf die vorhandene SQL Server 7 Instanz machen so dass
Du die Datenbank nicht erneut erstellen musst.

Zum Abschluss wäre es zwar besser ein DBCC DBREINDEX und
sp_updatestats ausführen, aber ich wage nicht zu schätzen,
wie das mit den doch knappen Plattenkapazitäten auf Deiner
Testmaschine ausgeht. bei engem Zeitfenster also erstmal weglassen.

>
> Per Massenkopieren die Echtdaten aus der Entwicklungsumgebung via CD
> in den Kundenserver gelegt. Mit den Problemen, dass das BCP (aber
> stolz behauptete, fertig zu sein) mittendrin 50 Mio Sätze unterschlug
> und der Server rd 60 Prozent der Usertabellen verlegte
> einschliesslich ALLER stored Procedures, die nicht vom Server waren:
> also unsere.

Das packen wir mal in die Historie und zu potentiellen Andekdoten für
Deine Lebensbiografie, da es heute nicht weiterhilft.

> Die Proceduren liefen wie erwartet und ich kam überhaupt nicht auf
> die Idee, dass ein reines Select from in die Tempdb schreibt.

Kleiner Irrtum. Der SQL Server arbeitet auch intern mit der tempdb
für Sortieroperationen und anderes mehr, wenn er mehr Platz braucht
als Speicher da ist. Deswegen sollte immer ausreichend Platz für
tempdb vorhanden sein und bei grösseren Installationen wie Deiner
eigentlich auch ein eignes Medium dafür verwendet werden (mehr unten).


>
> Das Sicherungskonzept auf diesem Rechner ist etwas mickrig: Da die
> Datenbank ein Datengrab und keine Produktionsumgebung wie z.Bsp
> Lagerbuchhaltung ist und nur Ergebnisse ausspucken soll, ist das mit
> der Sicherung nur bedingt dringend: Mit dem fernen Provider beim
> Kunden vereinbart: Der SQL-Server wird Samstags angehalten udn dann
> wird die ganze Maschine gesichert. Ein Restor der DB bedeutet dann
> eben ein Restore der gesamten Maschine. (Vorschlag von dem Provider
> des Kunden)

Nicht gerade optimal, aber vermutlich kann da keiner so richtig mit
einem SQL Server umgehen, also im Zweifelfall erstmal dabei belassen.
Besser wäre es die Grundkonfiguration des Rechners (meinetwegen Image)
zu sichern und die Datenbank Dateien via SQL Server BACKUP/RESTORE.

> Ich habe die u.a. Procedure jetzt gerade eben hier auf dem
> Entwicklugnsserver laufen lassen: Sie hat die Tempdb in Ruhe gelassen.

Solange Du da noch einen SQL Server 7 verwendest, ist das alles
nicht vergleichbar, siehe oben.

> Per Telefon gab mir ein Freund aus dem Osten (Hallo Ralf) den Tip
> während des Procedurelaufs mittels SP_LOCK nachzusehen,

sp_lock bringt uns hier erst mal nur wenig.
Wichtiger wäre der (vom SQL Server 2000) gelieferte Ausführungsplan
Wobei ich vermute das der so umfangreich wäre dass er in Textform
hier nicht mehr vernünftig darstellbar wäre. Falls Du jemand beim
Kunden überreden könntest den (geschätzten) Ausführungsplan im Query
Analyzer (STRG+L oder STRG+K) anzeigen zu lassen und als JPG irgendwo
auf einer Website oder auch als EMail - mit Ankündigung - zur Verfügung
zu stellen (bitte nicht als NG Posting da ich nichts über 100 KB sehe).


> Auf dem Kundenserver (SQL 2000) kriege ich so um die 95 Prozesse
> unter der User ID des Queryanalysers

Falls ihr durchweg das gleiche Benutzerkonto (Standardlogin) verwendet:
Ist die Datenbank bereits aktiv und hocken da somit andere Benutzer
drauf? Oder läuft da noch mehr ab?


> folgend die Procedure, die tückische:

ich habe mir die Prozedur mal etwas behübscht (und evtl. verunstaltet),
um da einigermassen durchzusteigen und einige Kommentare dazu geschrieben,
weiteres dazu unten:

ALTER PROCEDURE sumbrteam_jahr_dc

-- Falls mit wechselnden Jahren und dort unterschiedlicher
-- Verteilung kann der Aufruf mit WITH RECOMPILE sinnvoll sein
-- um optimale Ausführungspläne zu haben.
@imjahr smallint=2000
as
SELECT

-- Distinct raus (da schon GROUP BY)
distinct

g.baureihe as Baureihe,
kps.pfteam_nr as [Pf-Team],
kps.pfteam_benennung as [PF-Benennung],
SUM(g.kostensumme) as KostenGesamt,
SUM(g.nebenkosten) as [Nebenkosten],
SUM(g.lohnkosten) as [Kosten Lohn],
SUM(g.materialkosten) as [Kosten Material],
SUM(g.mkz) as [Kosten Material-NK],
SUM(g.betreuungsleistg) as [Kosten Betreuung],
bininjahr as Jahr

FROM gukasdaten as g

-- Für alle die jeweiligen Tabellem sollten einen (Clustered) Index haben
-- soweit nicht anderweitig mit höhrer Priorität besetzt


-- Zusammenfassen des indirekten Bezugs für kps.pfteam_nr
-- evtl. zusammenfassbar als abgeleitete Tabelle, da als
-- indirekter Verweis oft verwendet, je nach Variationen (besonders bei
-- wenigen Teams) evtl. denkbar eine Vorselektion über temporäre Tabelle
INNER JOIN ssl_pfteam
ON g.pf_ssl = ssl_pfteam.ssl_nr


INNER JOIN known_pfteams as kps
ON kps.pfteam_nr = ssl_pfteam.pfteam_nr

-- (NUR) in Ausschluss verwendet -> Verlagern?!?
INNER JOIN pfteam_sa_ein as pfsein
ON kps.pfteam_nr = pfsein.pfteam_nr
INNER JOIN pfteam_prod_datum as pprod
ON kps.pfteam_nr = pprod.pfteam_nr
INNER JOIN pfteam_sa_aus as pfsaus
ON kps.pfteam_nr = pfsaus.pfteam_nr

-- Für die folgenden JOINS sind keine Verweise in Klauseln oder Feldliste
-- Dies könnte also entweder (teilweise) entfallen, oder wenn die JOINS
-- als Ausschluss Kriterium verwendet werden in EXISTS umwandeln,
-- (gilt besonders wenn 1:N mit grossem N)


INNER JOIN pfteam_sca
ON kps.pfteam_nr = pfteam_sca.pfteam_nr AND g.sca_art = pfteam_sca.sca

INNER JOIN pfteam_karform as pkar


ON kps.pfteam_nr = pkar.pfteam_nr AND g.kar_form = pkar.kar_form

INNER JOIN gebietsliste as geb
ON geb.landcode_dc = g.gebiet
INNER JOIN pfteam_gebiet pfgeb
ON pfgeb.pfteam_nr = kps.pfteam_nr AND pfgeb.gebietsname_dc = geb.gebietsname_dc
INNER JOIN pfteam_baureihe as pbr


ON kps.pfteam_nr = pbr.pfteam_nr AND g.baureihe = pbr.baureihe

WHERE (g.bininjahr = @imjahr)
AND (g.sca_typ <> 'M')
AND g.sparte IN ('00','01')
AND g.gar_obj IN ('G','g')
AND g.tga = '0'
-- In JOIN?
AND g.pf_ssl NOT IN ('99800','99930')
AND LEFT(g.pf_ssl_bld,1) <> '9'
AND g.istamg = 0

-- Möglich wäre in JOIN Klausel verlagern oder EXISTS???
AND g.prod_datum BETWEEN pprod.ab_prod_datum AND pprod.bis_prod_datum


-- Wenn 1: N durch [NOT] EXISTS ersetzen
-- Wenn irgendmöglich die getrennten NOT IN und IN zusammenfassen
-- Clustered Index auf WHERE Klausel Teile
AND g.fahrgestellnr NOT IN
(
SELECT saf.fahrgestellnr
FROM sa_aktuellefins as saf
WHERE saf.fahrgestellnr = g.fahrgestellnr
AND saf.sa_code = pfsaus.sa_code
AND pfsaus.pfteam_nr = kps.pfteam_nr
)
AND g.fahrgestellnr IN
(
SELECT saf.fahrgestellnr
FROM sa_aktuellefins as saf
WHERE saf.fahrgestellnr = g.fahrgestellnr
AND saf.sa_code = pfsein.sa_code
AND pfsein.pfteam_nr = kps.pfteam_nr
)

GROUP BY
g.bininjahr,
g.baureihe,
kps.pfteam_nr,
kps.pfteam_benennung
HAVING SUM(g.kostensumme) > 0

-- besser identisch zu GROUP BY also g.bininjahr als erstes
-- da nur ein Jahr sollte dies keine Änderung der Reihenfolge bewirken
-- ganz streichen, wenn die Ausgabe in eine andere Tabelle erfolgt
ORDER BY g.baureihe,kps.pfteam_nr


Die obigen Kommentare sind alle mit grösster Vorsicht zu geniessen,
denn mir fehlen dafür zuviel Informationen wie genauere Zeilenangaben
für einige der Teilabfragen, vorhandene und genutzte Indizes uam.
Und da ich keinerlei "Gefühl" für die Dateninhalte habe, liege
ich womöglich stellenweise vollkommen daneben.

Und einiges mag der SQL Server ohnehin selbst rausfinden, aber ohne
den Ausführungsplan zu sehen, muss ich im Nebel stochern:

> Dabei ist die etwas grössere Datei die gukasdaten mit rd 15 Mio
> Sätzen und die nächste die sa_aktuellefins mit rd 5,5 Mio Sätzen. Die
> anderen haben dann so zwischen 80 und 200.000 Sätzen

Und wieviel Ausgabezeilen kommen dabei am Ende für ein Jahr heraus?

Deine Abfrage wird vermutlich in einen Table Scan über die "gukasdaten"
rauslaufen, wobei die diversen Joins evtl. in mehrere Hashes umgesetzt
werden. Dies wird zur Erstellung von (mehreren) Arbeitstabellen in tempdb
führen. Ein Optimierungsansatz müsste darauf hinauslaufen, die Zahl
(oder Grösse) der erzeugten Arbeitstabellen zu minimieren.

Kandidaten sind für mich da einmal der JOIN über "ssl_pfteam" und
"known_pfteams", da alle weiteren Verknüpfungen darauf aufsetzen.
Du solltest mal den Ausführungsplan darauf prüfen, welche Verknüpfung
der SQL Server dafür auswählt und welchen Einfluss sie auf die weiteren
Verknüpfungen haben.

Wenn dabei nur relative wenige Daten bei rauskommen (wenn Team
annähernd das ist was ich vermute), so sollte es da mehrere Möglichkeiten
geben. Erstellen einer Arbeitstabelle in einem einleitenden Schritt,
eine partionierte Sicht (funktioniert allerdings nur wenn auch der
SQL Server eine Enterprise Version ist).
Dies sollte dann mit einem entsprechenden Index in der "gukasdaten"
korrespondieren.

> Die Procedure summiert Kosten auf Kostenstellen auf, sie muss diese
> Kosten eindeutig zuordnen können, daher waren neben den vielen Joins
> die beiden Subselects nötig.

Die IN Klausel der beiden Subselect könnte u. a. eine der tempdb
Auffüller sein. Denn in der Regel erstellt der SQL Server dafür
häufig eine nach Eingabe sortierte Arbeitstabelle um den
Auswahlvorgang zu beschleunigen - ausgenommen er kann direkt
über einen clustered Index rüberlaufen. Je nach Anzahl der
Fahrgestellnummern könnte da einiges bei rauskommen. Da die beiden
Selects sich sehr stark ähneln und vermutlich durch das IN / NOT IN
Wechselspielchen einiges wechselseitig ausschliessen, kommt da evtl
einiges zusammen.
Wenn eine Bedingung mehrmalig auf der N Seite (hier fahrgestellnr
in "gukasdaten") vorkommt ist es zum einen häufig günstiger ein EXISTS
zu verwenden (wenns der SQL Server nicht selbst macht).

Auch sollte man versuchen, die NOT IN Klausel als NOT EXISTS in
das Subselect mit IN (wäre dann EXISTS) zu verlagern, so dass nur
eine Aussschlusstabelle dabei herauskommt.

Weitere Kandidaten sind die diversen JOINS, die nicht in der Feldliste
auftauchen und nur als Ausschlusskriterium fungieren. Dies würde ich
allerdings mit weniger Priorität betrachten, vorausgesetzt die Tabellen
haben einen Clustered Index auf der Bedingung und es gibt einen einen
korrespondierenden Index in gukasdaten. Und wenn, erst einmal die
vom Volumen her grösseren Tabellen-Exemplare.

Einige von den WHERE Bedingungen wie der Datumsbereich könnten zudem
in den JOIN Teil verlagert werden (wenns der SQL Server nicht selbst
findet und meint da einen zusätzlichen Schritt einbauen zu müssen).

Fürs Testen: Da Deine Prozedur ja etwas länger braucht, würde ich
erstmal nur die geschätzten Ausführungspläne (STRG+L im QA) betrachten.
Aber wie einleitend gesagt: Das gibt nur Sinn wenn Du es auf der
gleichen SQL Server Version und SP (also 2000 SP3) machst, sonst
läufst Du womöglich in die Irre.

>
> Laufzeit der Procedure gerade eben 18:54 auf Dual PIII 1000Mhz 1GiG
> RAM PC133 Platte 105 Gig (Raid 0 SCSI U160) bei DB-Grösse 83 Gig,
> davon 10,5 Gig frei:
> Laufzeit der Procedure bei letzem fehlerfreien Lauf (am 22.10) 6:17
> auf dem Kundenserver Dual XEON 2800 3GiG RAM PC2100 Platte 120 Gig
> (RAID 5 U320) bei DB-Grösse 75 Gig, davon 4,5 Gig frei

Auf Dauer - nur je nach Kooperationsbereitschaft und Budget sollte
man das auf später vertagen: Optimaler wäre es wenn tempdb auf
einem eigenen Medium (und dann besser RAID 1 oder auch 0) liegen
würde.

Gruss
Elmar

Alexander Bierig

unread,
Nov 19, 2003, 7:02:26 AM11/19/03
to
Grüss Dich Elmar,


hat jetzt zwar etwas gedauert meine Antwort, ich habe versucht Deine
Ratschläge und die der anderen Helfer hier umzusetztn.


Dir möchte ich stellvertretend für alle die Helfer danken für die wertvolle
Hilfe, die ich erhalten habe.

Ist echt toll, soviel Hilfe zu erfahren.

Alexander Bierig

unread,
Nov 19, 2003, 7:24:38 AM11/19/03
to
Grüss Dich Elmar,


>
> sp_lock bringt uns hier erst mal nur wenig.
> Wichtiger wäre der (vom SQL Server 2000) gelieferte Ausführungsplan

...


> Analyzer (STRG+L oder STRG+K) anzeigen zu lassen und als JPG irgendwo
> auf einer Website oder auch als EMail - mit Ankündigung - zur Verfügung
> zu stellen (bitte nicht als NG Posting da ich nichts über 100 KB sehe).

ich habe den Ausführungsplan der beiden Maschinen ins Netz gestellt: (wenns
noch jemanden interessiert)
Aufzurufen ist die Seite (nicht klickbar) unter
http://www.taxi-stuttgart.de/werbung/sqlserver.htm
und dort den Links folgen

Es gelang mir nicht, auf der Kundenmaschine einen Adobe zu erhalten, daher
ist vom 2K SQL nur der Report verfügbar.


> > Dabei ist die etwas grössere Datei die gukasdaten mit rd 15 Mio
> > Sätzen und die nächste die sa_aktuellefins mit rd 5,5 Mio Sätzen. Die
> > anderen haben dann so zwischen 80 und 200.000 Sätzen
>
> Und wieviel Ausgabezeilen kommen dabei am Ende für ein Jahr heraus?

derzt rd 900


>
> Auf Dauer - nur je nach Kooperationsbereitschaft und Budget sollte
> man das auf später vertagen: Optimaler wäre es wenn tempdb auf
> einem eigenen Medium (und dann besser RAID 1 oder auch 0) liegen
> würde.

Du weist Doch: Jeder muss sparen.


Das wirklcih verblüffende ist:

die Maschine ist jetzt ohne Änderung irgendeiner Einstellung (die geäderten
Proceduren sind extern auf Platte gespeichert)
rd zwei Wochen gelaufen.

Wir konnten somit den dringend notwendigen Datenabgleich machen und suchen
jetzt nach den Ursachen der Differenzen zu den vom Kunden bisjetzt händisch
erstellten Daten.

Das ist für mich die wirkliche Rätselfrage: Wieso die Maschine jetzt
plötzlich läuft.

Ich danke nochmals für deie tolle Hilfe

MfG
Alex.

>
> Gruss
> Elmar

Alexander Bierig

unread,
Nov 19, 2003, 7:32:26 AM11/19/03
to
Grüss Dich Elmar,


> -- Distinct raus (da schon GROUP BY)
> distinct
>
> g.baureihe as Baureihe,
> kps.pfteam_nr as [Pf-Team],
> kps.pfteam_benennung as [PF-Benennung],
> SUM(g.kostensumme) as KostenGesamt,
> SUM(g.nebenkosten) as [Nebenkosten],
> SUM(g.lohnkosten) as [Kosten Lohn],
> SUM(g.materialkosten) as [Kosten Material],
> SUM(g.mkz) as [Kosten Material-NK],
> SUM(g.betreuungsleistg) as [Kosten Betreuung],
> bininjahr as Jahr
>
> FROM gukasdaten as g
>
> -- Für alle die jeweiligen Tabellem sollten einen (Clustered) Index haben
> -- soweit nicht anderweitig mit höhrer Priorität besetzt
>


>


> WHERE (g.bininjahr = @imjahr)
> AND (g.sca_typ <> 'M')
> AND g.sparte IN ('00','01')
> AND g.gar_obj IN ('G','g')
> AND g.tga = '0'
> -- In JOIN?
> AND g.pf_ssl NOT IN ('99800','99930')
> AND LEFT(g.pf_ssl_bld,1) <> '9'
> AND g.istamg = 0
>
> -- Möglich wäre in JOIN Klausel verlagern oder EXISTS???
> AND g.prod_datum BETWEEN pprod.ab_prod_datum AND pprod.bis_prod_datum
>
>
> -- Wenn 1: N durch [NOT] EXISTS ersetzen
> -- Wenn irgendmöglich die getrennten NOT IN und IN zusammenfassen
> -- Clustered Index auf WHERE Klausel Teile


zu den Indexen habe ich noch einige Verständnissfragen:

Ich habe das so verstanden, dass ersten je Tabelle nur ein Clustered Index
zulässig/möglich ist Bei vielen Indexen ist daher für mich nciht kalr
WELCHEN davon als Clusterd.

Und das andere ist: Ich ging immer davon aus, dass man in den Index (und
zwar inder gesuchten Reihenfolge) die Felder der Abfrageergebnisse aufnehmen
soll: Sofern damit eine halbwegs vernünftige Indexierung machbar ist (auf
ein Bitfeld oder eine Feld, welches nur 5 verschiedene Inhalte kennt ist das
bei meiner Datenmenge nicht sinnvoll)

Damit habe ich unterschiedlich viele Indexe je Tabelle, angelegt um
vernünftige Antwortzeiten zu erhalten und wenn ich das richtig sehe, tut der
Server ja auch noch etliche generieren.
Oder muss/sollte ich zusätzlich noch dei Felder der Where-bedingungen in dei
Schlüssel aufnehmen?

Christoph Muthmann

unread,
Nov 19, 2003, 9:34:28 AM11/19/03
to
Alexander Bierig wrote:
> [snip]

> zu den Indexen habe ich noch einige Verständnissfragen:
>
> Ich habe das so verstanden, dass ersten je Tabelle nur ein Clustered
> Index zulässig/möglich ist Bei vielen Indexen ist daher für mich
> nciht kalr WELCHEN davon als Clusterd.
>
> Und das andere ist: Ich ging immer davon aus, dass man in den Index
> (und zwar inder gesuchten Reihenfolge) die Felder der
> Abfrageergebnisse aufnehmen soll: Sofern damit eine halbwegs
> vernünftige Indexierung machbar ist (auf ein Bitfeld oder eine Feld,
> welches nur 5 verschiedene Inhalte kennt ist das bei meiner
> Datenmenge nicht sinnvoll)
>
> Damit habe ich unterschiedlich viele Indexe je Tabelle, angelegt um
> vernünftige Antwortzeiten zu erhalten und wenn ich das richtig sehe,
> tut der Server ja auch noch etliche generieren.
> Oder muss/sollte ich zusätzlich noch dei Felder der Where-bedingungen
> in dei Schlüssel aufnehmen?

Hallo Alex,
zum ersten Punkt Clustered Index:
Einsatzbereiche gruppierter Indizes:
- Für Abfragen mit Wertebereichen
- Für Sortierungen
- Für eindeutige Schlüssel

Es kann nur einen geben! Daher die wichtigste(n) Abfrage(n) herausfinden!
Dafür passend einen gruppierten Index anlegen.

Zweiter Punkt: Welche Felder gehören in einen Index?
Du solltest alle Felder die in der Where-Bedingung auf Gleichheit geprüft
werden plus dem ersten auf Ungleichheit aufnehmen.
Falls Order By oder Group By definiert ist, könnte man auch diese Felder
aufnehmen. Verwende mal den Index-Tuning-Wizard und schau Dir die Ergebnisse
an. Am besten im Query Analyzer ein Statement markieren und mit Ctrl+I den
Wizard aufrufen.

Dritter Punkt: Wieviele Indizes?
Deine Vermutung, daß der Server Indizes anlegt ist falsch. Sie erscheinen
zwar im Taskpad unter Indizes, sind aber eigentlich Statistiken. Diese
helfen dem Optimizer zwar bei seinen Entscheidungen, sind aber nicht als
schneller Zugriffsweg zu verwenden.

Einen schönen Tag noch,
Christoph
--
(Please post ALL replies to the newsgroup only unless indicated otherwise)


Christoph Muthmann

unread,
Nov 19, 2003, 9:38:15 AM11/19/03
to
... und noch zur Ergänzung:

Man sollte den Schlüssel von gruppierten Indizes relativ kurz halten. Dieser
Schlüssel ist der Zeiger auf die Daten für alle anderen Indizes auf der
Tabelle. Langer Schlüssel -> Langer Zeiger.

Man sollte den Schlüssel von gruppierten Indizes möglichst Unique
definieren. Andernfalls hängt der SQLServer noch 4 Byte an, um diesen Unique
zu machen. Denn der Schlüssel ist ja der eindeutige Zeiger auf die Daten. s.
o.

0 new messages