Gerüchte und Mythen über SQL Server

Gerüchte und Mythen über SQL Server

  • Comments 3
  • Likes

 

In meiner beliebten Reihe „Fragen von Kunden“ gibt es heute mal einige Gerüchte zu SQL Server, die von Wettbewerbern genannt werden um den Kunden zu verunsichern. Ich bin schon ziemlich erstaunt, welche Informationsdefizite bestehen…

Zu den Gerüchten:

1. Der SQL Server kann keine vernünftigen Locks (Sperren) durchführen. Er lockt (sperrt) immer seitenweise, was dazu führt, dass man unvorhersehbares Laufzeitverhalten erzeugt.

Tja, SQL Server 6.5 hat noch ganze Seiten gesperrt…

Seit SQL Server 7.0 gibt es Row Level Locking. Allerdings wählt SQL Server bei großen Mengen von Datenänderungen auch manchmal Page (Seite) oder gar Table Locks, da dies Hauptspeicher und vor allem die Zeit zum Setzen und Entfernen der Locks spart. Hier ist SQL Server deutlich effizienter als andere Datenbanksysteme. Wem dieses Verhalten nicht gefällt, der kann einen ROWLOCK Table Hint in den Abfragen verwenden oder Page Locks für einen Index mit der Index Option ALLOW_PAGE_LOCKS = { ON | OFF } deaktivieren. Bei manchen Vorgängen, insbesondere DDL-Statements wie ALTER TABLE ist allerdings ein Table Lock unumgänglich, das ist in anderen Datenbanken auch so.

2. SQL Server verwendet pessimistisches Locking. Dadurch blockieren Leser Schreiber und umgekehrt und die Parallelität wird gesenkt

Ausschließlich pessimistisches Locking wurde bis SQL Server 2000 verwendet…

Seit SQL Server 2005 hat der Kunde die Wahl, ob er optimistisches oder pessimistisches Locking verwenden will, wobei pessimistisches nach wie vor der Standard ist.

Worum geht es? Nehmen wir an, Transaktion A will einen Datensatz schreiben, Transaktion B denselben Datensatz lesen (bei Row Level Locking). Beide Transaktionen sind noch nicht abgeschlossen. Klar ist, dass Transaktion B auf keinen Fall den noch nicht committeten neu geschriebenen Wert lesen darf (Dirty Read), denn es kann ja sein, dass Transaktion A zurückgerollt wird. Nun hat die Datenbankengine zwei Möglichkeiten:

Pessimistisches Locking: Wenn der Datensatz von Transaktion B geschrieben wird setzt die Engine einen exklusiven Lock auf den Datensatz. Transaktion B will vor dem Lesen einen Shared Lock haben, bekommt den aber wegen dem exklusiven Lock erst nach Abschluss von Transaktion A.

Optimistisches Locking: Bis zum Abschluss der Transaktion A wird neben den geänderten Daten auch die alte, committete Version des Datensatzes gehalten (in tempdb). Dadurch kann Transaktion B die alte Version der Daten lesen und es ist kein Shared Lock notwendig. Das entspricht zum Beispiel dem Verhalten in Oracle (Oracle verwendet die Begriffe pessimistisch und optimistisch allerdings ein wenig anders, da es die hier angegebene erste Variante gar nicht gibt). Optimistisches Locking können Sie in SQL Server mit READ_COMMITTED_SNAPSHOT oder TRANSACTION ISOLATION LEVEL SNAPSHOT (mit leicht unterschiedlichem Verhalten) verwenden. Mehr dazu hier: http://msdn.microsoft.com/en-us/library/ms179599.aspx

Warum gibt es nun beide Varianten? Weil pessimistisches Locking ressourcenschonender und für Szenarien besser geeignet ist, wo meist unterschiedliche Datensätze zugegriffen werden (z.B. Lagerhaltung). Optimistisches Locking ist hingegen flexibler.

3. Der SQL Server ist fast unbezahlbar, da man keine vernünftige Lizensierung durchführen kann, die eine unbeschränkte Anzahl von Usern (z.B. im Web-Betrieb) erlaubt.

SQL Server kann man auf Prozessor (bis 2008R2) bzw. Core (ab SQL 2012) Basis lizenzieren und damit beliebig viele Benutzer supporten. Und auch die kostenlose SQL Server Express Version ist in manchen kleinen Web-Szenarien eine Option.

Bei der Gelegenheit: Auch von Oracle gibt es ja eine kostenlose Express Version (XE). Allerdings wird diese im Gegensatz zu SQL Server Express nicht gepatcht, auch nicht bei den reichlich vorhandenen Sicherheitslücken. Damit ist sie für Web-Aufgaben (und eigentlich für fast alle Aufgaben) komplett ungeeignet.

4. Der SQL-Server verwendet immer feste, nicht anpassbare Blockgrößen bei der Speicherung. Oracle kann hier zwischen 2K und 32K skalieren.

Das ist richtig, SQL Server verwendet immer 8k Datenseiten für die Speicherung. Die gesamte Datenbankengine und das IO Subsystem ist daraufhin optimiert, und auch Hersteller von Storagelösungen können sich darauf einstellen. In Oracle gibt es die Möglichkeit, die Blockgröße anzupassen, aber nur die wenigsten Kunden nutzen diese Möglichkeit. Zumal verschiedene Blockgrößen innerhalb einer Instanz zu einer Fragmentierung des Hauptspeichers führen würden – man kann nun mal nicht eine 32kB Seite in den Platz laden, der von 4 8kB Seiten freigegeben wurde, wenn dieser Platz nicht hintereinander liegt.

Die Performanceergebnisse von SQL Server geben uns hier wohl recht… Und bei größeren Datenmengen verwendet SQL Server Read Ahead mit Lesegrößen bis zu 1024 kB, um effizienter auf das Storagesystem zuzugreifen.

5. Der SQL-Server hält sich nicht an die ANSI-Standards und hierdurch ist Interoperabilität nicht gewährleistet.

Es ist zwar richtig, dass es geringe Unterschiede zwischen SQL Server und ANSI SQL gibt, aber meines Wissens gilt dies auch für jedes andere relationale Datenbank. Einige der Differenzen zwischen Oracle SQL und ANSI SQL finden sich hier: http://de.wikipedia.org/wiki/Oracle_(Datenbanksystem)#Abweichungen_vom_ANSI-SQL-Standard. Allerdings ist diese Liste bei weitem nicht vollständig. So ist zum Beispiel die Oracle SEQUENCE-Syntax nicht ANSI compliant (die von SQL Server 2012 schon).

Im Falle von SQL Server liegen die Unterschiede vor allem in Datentypen (wie TIMESTAMP), die bereits vor Verabschiedung des ANSI Standards anders verwendet wurden.

Allgemein haben allerdings alle großen Datenbanksysteme viele Features, die weit über den ANSI Standard hinausgehen. Daher ist Interoperabilität immer nur dann möglich, wenn beim Schreiben des SQL Codes ausdrücklich darauf geachtet wird, nur standardisierte Sprachkonstrukte zu nutzen.

6. Es gibt kein Äquivalent zu den PLSQL-Packages des Oracle, das ein Lifecycle-Management sowie eine Verteilungs-Strategie zulassen würde.

Da hätten wir ja eines der nicht standardkonformen Oracle-Features. In ANSI SQL gibt es kein CREATE PACKAGE…

SQL Server hat zwar keine Packages, wer möchte kann allerdings Schemas stattdessen zur Strukturierung des Codes verwenden (für die Oracle-Fraktion: in SQL Server werden Schemas anders verwendet als in Oracle. Ein Oracle-Schema entspricht mehr einer SQL Server Datenbank)

Für Lifecycle Management und Verteilungsstrategie gibt es allerdings in SQL Server deutlich bessere Varianten. Insbesondere die Möglichkeit der Integration von SQL Server Management Studio mit Quellcodeverwaltungssystemen, die neuen SQL Server Data Tools mit ihrem kompletten round trip engineering für Datenbankcode, die DAC-Pakete und die Integration mit Visual Studio Team System wären hier zu nennen…

Wie andere Datenbanksysteme auch unterliegt SQL Server einer ständigen Weiterentwicklung, um das geeignete Datenbanksystem zu finden sollte man immer über die aktuellen Möglichkeiten informiert sein. Ich hoffe ich konnte mit diesen Beispielen zeigen wie wichtig dies ist.

Zum Abschluss noch ein paar Links zum Thema SQL Server Mythen:

Gruß,
Steffen

Comments
  • <p>Sehr gute Antworten auf diese Mythen, auch für Menschen, die sich mit beiden Systemen seit Jahren befassen.</p>

  • <p>Wie sieht es im Bereich Hash Index aus, sowie Hash based placement... da sehe ich bei MS nichts</p> <p style="padding-left:30px;">Antwort: Es ist richtig, dass SQL Server keine Hash Indizes hat. Allerdings braucht man etwas &auml;hnliches recht selten, und man kann es z.B. zum Ablegen von Key-Value-Paaren &uuml;ber die integrierten Hashfunktionen emulieren. Was ist denn bei Ihnen genau der Anwendungsfall?</p> <p style="padding-left:30px;">Gru&szlig;,<br />Steffen</p>

  • <p>Es ist im SQL Server sehr einfach einen HASH Index anzulegen, auch wenn es keine eigenständige Syntax für den Hash Index gibt. Durch die Möglichkeit der berechneten Spalten (Computed Columns) kann einfach eine HASH Funktion in die Tabelle integriert werden:</p> <p>-- Erstellung eines Checksum Indexes.</p> <p>ALTER TABLE Production.Product</p> <p>ADD cs_Pname AS CHECKSUM(Name);</p> <p>CREATE INDEX Pname_index ON Production.Product (cs_Pname);</p> <p>Die Abfrage erfolgt dann mit einer dualen Strategie, um Duplikate bei den HASH Werten auszuschließen:</p> <p>SELECT * FROM Production.Product</p> <p>WHERE CHECKSUM(N&#39;Fahradsattel&#39;) = cs_Pname AND Name = N&#39;Fahradsattel&#39;;</p> <p>Besonders effizient ist dieses Verfahren, wenn längere, alphanumerische Text Felder indiziert werden sollen, da der Lookup lediglich über den Hashwert erfolgt und nicht über den gesamten String. In wieweit dieser Aufwand wirklich zielführend ist und nicht vielleicht ein COLUMN STORE INDEX die besser Wahl ist hängt deutlich vom Einsatzzweck ab.</p> <p>Gruß</p> <p>Ralph Kemperdick</p>

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment