Datenbanken: was ist gutes und was ist schlechtes Datenbankdesign? Überlegungen zu GUIDs als Index


Oft stellt sich die Frage, was ein gutes Datenbankdesign ist und was nicht. O/R-Mapper gehören quasi schon fast zum guten Ton einer jeglichen Anwendung. Die “Schmerzen” welche Joins und dergleichen verwenden werden uns durch O/R Mapper oftmals abgenommen. Was ich häufig sehe und auf den ersten Blick auch sehr gut aussieht ist ein GUID als Index zu verwenden. Dies sieht dann im Quellcode in etwa so aus:

[ActiveRecord]
public abstract class DomainObject : IDomainObject
{
    [PrimaryKey]
    public Guid Id
    {
        get;
        set;
    }
}

HINWEIS: Dieses Domänenobjekt ist – wie an [ActiveRecord] ersichtlich – mit ActiveRecord erstellt.

Einen GUID als Primary Key zu verwenden ist keine Seltenheit – ich mache es selbst sehr oft (wir müssen ja alle skalieren und bei unseren stark frequentierten Anwendungen kann es schon vorkommen das ein “long” oder “int” nicht ausreicht Smiley. Also ist es OK einen GUID zu verwenden?

Überlegen wir uns mal, wie es vom wirtschaftlichen Standpunkt betrachtet aussieht. Was ist am einfachsten zu skalieren, was kostet am wenigsten? Es dürfte klar sein das das günstigste der Plattenspeicher ist. Wo es wirklich teuer wird ist die CPU Last. Daher gilt es, eine Datenbank so zu erstellen dass die CPU-Last minimiert wird.

Ein kleiner Einblick, was GUIDs in der Datenbank bewirken gibt Kimberly L. Tripp in seinem Blog-Post “Disk space is cheap – that is not the Point”. Kimberly hat 3 unterschiedliche Testläufe durchgeführt, die Ergebnisse sind mit GUIDs fatal. Hier der Überblick bei 10.000 Inserts:

Dauer mit Integer als IDs: 17 Sekunden
Dauer mit GUIDs als IDs: 5:07 Minuten.

WOW, ein ziemlich heftiger Unterschied, oder? Befragt man den SQL-Server Experten Klaus Aschenbrenner, so sieht seine Antwort ähnlich aus:

*) Du generierst durch GUIDs random IO auf der Disk
*) Du produzierst unnötigen Speicherplatzverbrauch (GUID ist 16 Bytes lang - ist verdammt lang für einen PK)
*) JOINs sind 4x so teuer, als wenn du eine INT IDENTITY verwendest (16 Bytes vs. 4 Bytes)
*) Data Compression bringt mit GUIDs fast keinen Gewinn
*) Datenbank Backups werden größer
*) Die External Index Fragmentation ist standardmäßig auf ca. 99%, dh. jede Page ist out-of-order
*) Non-Clustered Indizes werden größer und unperformanter

Also spricht einiges gegen GUIDs in diesem Fall.

Nun frag an euch: könnt Ihr diese Behauptungen wiederlegen? Welche Erfahrungen habt Ihr zu diesem Thema gemacht? Postet eure Erfahrungen/Ideen zu diesem Thema!

Links:

Disk space is cheap von Kimberly L. Tripp: http://www.sqlskills.com/BLOGS/KIMBERLY/post/Disk-space-is-cheap.aspx

Blog von Klaus Aschenbrenner: www.csharp.at


Skip to main content