Glorf.it

Glorf IT

Bedenkliches aus dem IT-Alltag

13. August 2007 um 12:38

SQL-Server undokumentiert: DBCC PAGE

Als ich die Systemdatenbank mssqlsystemresource neulich mal untersucht, versucht ich mein Glück zunächst mit einem nur halb dokumentierten DBCC-Befehl: ersteht nicht in den Books-Online, aber in der Knowledgebase steht dann doch eine Anleitung.

Der Aufruf ist recht schlicht und kann aus einer beliebigen Datenbank erfolgen:

DBCC PAGE( {dbid|dbname}, filenum, pagenum [, printopt] [, cache] [,logical] )

Damit der Output sichtbar ist, muss man dem SQL-Server vorher noch sagen, dass er an den Client geschickt werden soll und nicht etwa ins Errorlog:

DBCC TRACEON (3604)
DBCC PAGE (32767, 1, 1, 1)

Parameter Beschreibung
dbid ID der Datenbank
dbname Datenbankname
filenum Dateinummer (1 ist immer die MDF, 2 meist die LDF, usw.)
pagenum Seitennummer in der Datei
printopt optional:
0: Default; Buffer- und Page-Header
1: Buffer- und Page-Header; jeden Datensatz einzeln und die Satz-Offset-Tabelle
2: wie 1, aber alle Datensätze zusammen
3: wie 1, aber die Daten im Klartext
cache optional:
0: lädt die Seite "frisch" aus der Datenbank-Datei
1: zeigt die Seite aus dem Cache (Default)

Ich habe das zum Glück noch nicht oft benötigt, aber irgendwie finde ich es echt cool mir die Datenseiten so richtig ansehen zu können…

Siehe auch

12. August 2007 um 12:20

beliebte Performance-Fallen

Einer meiner Jobs ist die Analyse von Performanceproblemen bei unseren Anwendungen. Deswegen habe ich hier einfach mal ein paar typische Performance-Fallen bei datenbanknutzenden Anwendungen geschrieben. Natürlich ist es schwierig pauschale Ratschläge abzugeben. Es besteht immer die Gefahr platt oder arrogant zu wirken. So ist es nicht gemeint.
Das alles läuft unter dem Motto: Gefahren, die man kennt, kann man umschiffen…

* Nur die wirklich notwendigen Datensätze anfordern
Werden in der Anwendung beispielsweise Cursor verwendet (gerne bei ODBC oder MFC), dann werden oft nur die ersten 30 Datensätze lesen (mehr passt nicht auf den Bildschirm, der Rest wird dann nur im Bedarfsfalls gelesen (z.B. in einem virtuellen List-Control). Je nachdem welchen Cursor-Typ man verwendet und wie komplex das Statement ist, muss der SQL-Server aber dennoch alle vom Datensatz betroffenen Datensätze lesen, z.B. 10000, obwohl in der Regel nur die aktuellesten 20 tatsächlich von Kunden tatsächlich werden. Das gilt häufig dann, wenn der SQL-Server die Datensätze sortiert liefern soll, aber kein entsprechender Index da ist.

* Immer alle benötigen Daten auf einen Schlag anfordern
Ich sehe immer wieder, dass eine Reihe von Datensätzen aus einer Tabelle gelesen wird. Sagen wir mal die Daten einer Rechnung. Dann wird pro Rechnung nachgelesen wie der verantwortliche Sachbearbeiter – von dem ja nur die ID in dem Datensatz steckt – heißt. Dann wird der Name des Kunden (aus dem Gleichen Grund) pro Rechnung nachgelesen. Das sollte man bitte auf keinen Fall machen. Damit belegt man nur, dass der Chef das Geld oder die Zeit für eine SQL-Schulung nicht ausgeben wollte. Und kauft damit eine schlechte Performance ein.
Statt dessen verwendet man einen Join, um die beiden Namen zusammen mit den Rechnungsinformationen zu lesen. Das ist einfach und effizient.

* die Objektorientierung nicht um seiner selbst Willen durchziehen
Leider passiert es sonst regelmäßig, dass die aufgerufene Klasse, die ja meist nicht weiß in welchem Kontext sie gerufen wird, sich unsinnig verhält.
Beispielsweise soll der Status von allen Bestellungen eines Kunden auf "fakturiert" gesetzt werden, wenn die Rechnung dafür raus ging. Die beste Performance bekommt man wenn man nur ein einziges UPDATE dafür absetzt. Wenn man aber (vermeintlich) "objektorientiert" vorgeht, dann werden in einer Schleife alle Bestellungen durch genudelt, und pro Bestellung ein UPDATE abgesetzt. Das kostet unglaublich Performance und ist so als ob man jede Morgen für jedes einzelne Brötchen wieder einzeln zum Bäcker fährt. Dabei könnte man doch mit einer Fuhre alle 10 Brötchen mitbringen.

* Schleifen
Das gilt natürlich nicht nur für die objekt-orientierte Vorgehensweise: Das gilt für alle Programmiersprachen und Architekturen. Deswegen nenne ich es noch als eigenen Punkt: Jede Schleife kostet unnötig Zeit. Mehr Zeit als man denkt.

* keine oder unsinnige Clustered-Indexe
Den Primärschlüssel zum Clustered-Index zu machen ist nach meiner Erfahrung meistens suboptimal und lohnt sich nur bei zusammengesetzten Primärschlüsseln. Wenn man eine ID verwendet, dann sollte man Clustered-Index lieber auf ein oder mehrere fachliche Felder legen, die unter Umständen sogar Fremdschlüssel irgendwohin sind. Dadurch erreicht man, dass fachlich zusammengehörige Felder auf der gleichen oder wenigstens auf benachbarten Datenseiten liegen.
Der Clustered-Index sollte übrigens nicht zu "breit" sein, weil am SQL-Server-2005 die anderen Index nicht mehr auf die Datenseiten verweisen, sondern auf den Eintrag im Clustered-Index…

Früher hatte ich auch noch eine ganze Palette an Tricks zur Mikro-Optimierung auf Lager. Aber der Optimizer des SQL-Servers ist jetzt so clever geworden, dass die meisten zum alten Eisen gehören. Außerdem habe ich echt die Erfahrung gemacht, dass die dicken Brocken so viel Zeit verschlingen, dass sich die Mikrogeschichten (wie z.B. Parametrisierung) erst sehr spät rentieren…

11. August 2007 um 12:09

Fremdschlüssel-Falle

Wenn man sich mit Datenbanken beschäftigt, dann hat man immer wieder mit Fremdschlüssel zu tun. Ich bin ein großer Fan von Fremdschlüsseln: Wenn sie sprechend benannt wurden, dann kann man mit ihnen fremde Datenbanken gleich besser verstehen. Besonders weil ich dann gerne Datenbank-Diagramme mit dem Management Studio erstellen lasse… 😉

Der eigentliche Zweck ist aber natürlich praktischer: Es werden nur solche Werte zugelassen, die in der primäre Tabelle auch tatsächlich existieren, z.B. ein Mitarbeiter kann nur in einer Abteilung sein, die es auch wirklich gibt. Neben den Problemen mit historischen Daten, die sehr sauber modelliert werden müssen, gibt es ein Feature, das weitgehend unbekannt ist:

Wenn man NULL-Werte zulässt, dann ist NULL in den Fremdschlüsselwerten grundsätzlich erlaubt. Das ist bei einsegmentigen Schlüssel total einsichtig, bei zusammengesetzen führt es in der Regel zu Verblüffung. Ich mache mal ein Beispiel:

Ich habe eine Tabelle "primtab" mit dem Schlüssel bestehend aus pk1 und pk2. Und die Tabelle "reftab", die auf die Tabelle "primtab" verweist. Mit beiliegenden Code kann man ein Beispiel mit Daten anlegen.

create table primtab (
pk1 integer not null,
pk2 integer not null,
primary key(pk1, pk2),
misc integer
– …
)

create table reftab (
pk integer not null primary key,
fk1 integer null,
fk2 integer null,
foreign key (fk1, fk2) references primtab(pk1, pk2),
misc integer
– …
)

insert into primtab (pk1, pk2, misc) values (1,1,1)
insert into primtab (pk1, pk2, misc) values (1,2,1)
insert into primtab (pk1, pk2, misc) values (1,3,1)
insert into primtab (pk1, pk2, misc) values (2,1,1)
insert into primtab (pk1, pk2, misc) values (2,2,1)

insert into reftab (pk, fk1, fk2, misc) values (1,1,1,1)
insert into reftab (pk, fk1, fk2, misc) values (2,1,2,1)
insert into reftab (pk, fk1, fk2, misc) values (3,1,3,1)
insert into reftab (pk, fk1, fk2, misc) values (4,1,1,1)
insert into reftab (pk, fk1, fk2, misc) values (5,2,1,1)
insert into reftab (pk, fk1, fk2, misc) values (6,2,2,1)
insert into reftab (pk, fk1, fk2, misc) values (7,1,1,1)
insert into reftab (pk, fk1, fk2, misc) values (8,2,1,1)

Da für die Fremdschlüsselfelder fk1 und fk2 NULL erlaubt ist, kann man den Wert auch für Beide setzen.

Update reftab
set fk1=NULL,
fk2=NULL
where pk=1

Man kann aber auch nur einen der Werte auf NULL setzen:

Update reftab
set fk2=NULL
where fk2=1

oder

Update reftab
set fk1=NULL
where fk1=1

Für mich war das damals völlig unerwartet und erst nach endlosen Diskussionen in Newsgroups konnte ich mich damit abfinden…

10. August 2007 um 12:39

Eigene Fonts erstellen

Wenn man aus irgendeinem Grund einen eigenen Font anlegen möchte, dann muss man nicht nach teuren Tools greifen. Für den Hausgebrauch reicht auch einfach der mit Windows mitgelieferte Zeichensatz-Editor. Die Bedienung ist eigentlich gar nicht schwierig. Das Erstellen der Zeichen fand ich aber trotz der Hilfsmittel (Zeichen kopieren, Kontur anzeigen, …) doch recht mühsam. Das ist jedenfalls nichts was man mal eben so macht.

Besonders hilfreich für mich war die Referenz, die man im Menü unter Extras findet. Sonst hätte ich nicht gewusst wo welche Zeichen liegen. Im Zeitalter den Unicode sind es eben nicht bloß die aus der 7-Bit-Welt bekannten Zeichen… 😉

Zum Starten einfach unter Start\Ausführen "eudcedit" eingeben.

9. August 2007 um 12:06

schickes Zeiteisen für den Desktop

XClockSeitdem es Vista gibt fragen mich immer mehr Leute, ob die Uhr auf meinem Desktop aus Vista sei. Das stimmt aber einfach nicht, sie gab es schon lange vor Vista. Ich habe keine Ahnung, wie lange ich sie schon habe. Aber sie bietet echt nette Features und sieht schön aus:

  • Man kann zwischen unglaublich vielen Arten wählen, wie sie aussehen soll. Die meisten davon (oder alle?) kann man stufenlos transparent machen, die Größe verändern und die angezeigten Informationen verändern.
    Ich persönlich verzichte auf Datum und Sekundenzeiger.
  • Da sie immer oben ist, kann man sie durchklickbar machen, d.h. sie ist nicht im Weg.
  • Natürlich kann man auch mehrere Alarme festlegen, mit Sound und/oder Text.
  • Spielkinder können auch über PlugIns fehlende Funktionen nachladen.

Den Download gibt es auf der Seite www.tenzor.cz/clocx.

Hier noch zwei Beispiele:
XClock XClock in gelb

8. August 2007 um 12:31

not invented here

Ich frage mich immer mal wieder, warum es so schwierig ist, dass Entwickler einfach mal bereits vorhandene Softwaremodule verwenden anstelle alles neu zu schreiben. Man erzählt sich, dass es vor meiner Zeit in unserer Firma alleine 10 verschiedene Taschenrechner-Implementierungen in den verschiedenen PC-Produkten gab. Ale sahen unterschiedlich aus und hatten jeweils ein paar besondere Features.
Ich habe keine Ahnung, ob das stimmt, aber ich glaube das sofort.

Das Verhalten ist so schlimm, dass man dem sogar einen eigenen Namen gegeben hat, als sei es eine Krankheit: "not invented here"-Syndrom.

Hat es etwas mit den besonderern Eigenschaften eines Entwicklers zu tun (die Eigenschaften "des" Entwicklers sind ein interessantes Thema, dem werde ich mal nachgehen)? Immer das Beste erreichen zu wollen, anstelle eines Kompromisses?

Komischerweise pflichtet jeder bei, wenn man abstrakt von Wiederverwendung spricht: es spart Kosten, der Code ist getestet und muss nur von einem gewartet werden.

Andererseits erlebe ich gerade auch in meiner unmittelbaren Nähe, dass "ganz neue Werkzeuge" entwickelt werden, die vorhandenen in bestimmten Funktionen sehr ähnlich sind. Aber es ist eben nicht ganz genau das gleiche. Man müsste ja einen Kompromiss eingehen oder sich abstimmen oder in das andere Tool einarbeiten oder …

Ich habe selber erlebt, wie schwer es war sich bei einem Projekt von der technisch besten Lösung zu verabschieden: die Projektleitung entschied auf ein technisch minderwertiges System zu setzen, das aber schon da war. Was habe ich mich damals geärgert… Ich denke heute immer noch, dass wir die technisch schlechtere Lösung wählten, aber die Kunden sind mit dem Ergebnis sehr zufrieden. Sie sind geradezu begeistert. Der Grund liegt darin, dass wesentliche Teile der neuen Ideen umgesetzt wurden: innovative Ideen, die unseren Kunden jede Menge Geld einbringen können. und das auf der alten Basis… Das war für mich sehr lehrreich.

7. August 2007 um 12:23

Craig Freedman's WebLog

Wer sich für die Themen SQL-Ausführung und Zugriffspläne des Microsoft SQL-Servers-2005 interessiert, der wird auf dem Weblog von Craig Freedman fündig.

Er postet vergleichsweise wenig, aber ich finde die Artikel sehr gut. Sie sind fundiert und bleiben nicht an der Oberfläche ohne dabei zu lang zu werden. Seine Artikel über die Isolation-Level sind beispielsweise großartig, anbei ein paar Beispiele:

Aber Achtung: das ist keine leichte Entspannungslektüre… 😉

6. August 2007 um 12:18

Alles über DATETIME am SQL-Server

Was man immer schon mal über DATETIME am SQL-Server wissen wollte, aber nicht den leisesten Schimmer hatte, dass es wissenswert ist, hat Tibor Karaszi sehr schön beschrieben. Auf seiner Homepage findet sich wirklich alles, was man wissen sollte. Ideal für Einsteiger oder angehende Profis.

Gugst Du hier: "Tibor Karaszi's SQL Server pages"

Darauf kam ich durch eine sehr interessante Diskussion in der Newsgroup "microsoft.public.sqlserver.programming" (?) zwischen Joe Celko und Tibor Karaszi… 😉

5. August 2007 um 20:55

Infosammlung zu den Integration Services

Auf dem letzten bzw. ersten Regionalgruppentreffen der PASS-Franken empfahl schilderte jemand (war es Klaus Oberdalhoff?) Wilfried Färber als den absoluten Fachmann für die "SQL Server Integration Services" (SSIS). Beim erneuten Lesen des PASS-Newsletters vom Juli fiel mir die Adresse seiner Webseite ins Auge: www.SQLIS.de

Die Artikel auf seiner Webseite sind absolut beeindruckend. Wenn ich dann endlich dazu komme mit den SSIS rum zu spielen, dann kenne ich jetzt eine gute Anlaufstelle…

3. August 2007 um 13:14

Wahlcomputer noch unsicherer als erwartet

Puh, das ist ja ganz schön krass, was man da bei Heise lesen kann: "US-Wahlcomputer können keine vertrauenswürdigen Wahlen garantieren"
Wenn man sich das so ansieht, dann sind sie ja sogar noch unsicherer als erwartet:

"Das Diebold-System ist anfällig für Computerviren, die sich von Wahlmaschine zu Wahlmaschine und zwischen Wahlmaschinen und dem Wahlmanagementsystem ausbreiten", heißt es in dem am gestrigen Donnerstag veröffentlichten Gutachten, das die Wissenschaftler im Rahmen der von Kaliforniens Innenministerin Debra Brown initiierten umfassenden Sicherheitsüberprüfung der in dem Bundesstaat bisher eingesetzten und zertifizierten Wahlmaschinen erstellten; erste Ergebnisse aus der Überprüfung waren bereits Anfang der Woche bekannt geworden. "Ein großflächig angelegter Wahlbetrug in dem Diebold-System erfordert daher nicht unbedingt den direkten Zugriff auf eine große Anzahl von Wahlmaschinen".

Leider ist ja die Petition in D im Sande verlaufen. Die hochgeschätzten Würdenträger nahmen das wohl nicht richtig ernst… Irgendwie glaube ich nicht, dass die Untersuchung in den USA einen unserer Abgeordneten aufrütteln wird. Oder doch?

1. August 2007 um 21:43

Video zum Vorgehen bei defekten Datenbanken

Wer mal Mr. Paul Randal auf Video erleben will, der kann seinen extrem kurzweiligen Vortrag "Secrets of Fast Detection and Recovery from Database Corruptions" ansehen. Es lohnt sich, es ist geradezu ein MUSS für jeden DBA! Über eine Stunde voll mit wichtigen Tipps handlich verpackt.

Aber es gibt ein paar Schattenseiten:

  • Er redet sehr schnell, aber deutlich.
  • Man muss sich allerdings bei MS anmelden. Der alte Passport-Account tat's bei mir…
  • Ich musste es mit dem IE ansehen, Firefox klappte nicht.

Mir war übrigens nicht klar, dass Page-Checksums nicht für die TempDB berechnet werden.