Belastungstest

Knapp 100 gleichzeitige Anfragen, konkurrierende Schreibzugriffe und hohe Portabilität kennzeichnen die neue Version des iX -Datenbank-Benchmarks.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 5 Min.
Von
  • Jürgen Seeger

Wer mißt, mißt Mist’ ist eine alte Ingenieursweisheit, und dieser Satz ist vorbehaltlos auf die Informationstechnik übertragbar. Die besten Benchmark-Ergebnisse sind das Papier, auf dem sie veröffentlicht wurden, nicht wert, wenn gerade Ihre Anwendung die Systemressourcen auf völlig andere Art fordert als der Benchmark XYZ mit den Superergebnissen.

So weit die Vorrede. Trotzdem wird gerade im Computerumfeld gemessen, was das Zeug hält, mit SPECs und TPCs geworben, wahrscheinlich auch danach gekauft. Denn so wenig ein Benchmark über die Alltags-Performance einer speziellen Applikation aussagen mag - immerhin lassen sich Größenordnungen abschätzen. Es geht dabei nicht um Prozentpunkte oder gar Nachkommastellen, eher um Faktoren, um eine ungefähre Vergleichbarkeit. Wenn beispielsweise ein Computer bei der iX-SSBA Werte wie ein Pentium-166 liefert, sollte man ihn nicht für den Webserver mit 1 000 000 Hits pro Tag einsetzen.

Solcher Art erste Anhaltspunkte liefert auch SQLBench2, erstmals in einer Vorversion eingesetzt im Linux-DBMS-Vergleich [1]. Die ‘2’ im Namen erklärt sich durch die Tatsache, daß er auf dem unter Datenbankern als SetQuery bekannten Meßverfahren aufbaut, das von seinem Schöpfer Patrick E. O’Neill in Datamation und einer sehr frühen iX (3/90, Seite 63) vorgestellt wurde.

SetQuery simuliert Abfragen aus dem Bereich Decision Support: aus einer großen Menge von Datensätzen werden bestimmte Teilmengen gewonnen beziehungsweise Operationen auf diesen durchgeführt. Die Art der Abfragen wurde auf Basis von Umfragen in den DV-Abteilungen verschiedener US-amerikanischer Firmen gewählt. SetQuery beinhaltet ausschließlich lesende Operationen auf einer Million Datensätzen mit Zufallszahlen und -Strings und arbeitet mit einfachen bis komplexen SQL-Statements. Alle Daten liegen in einer Tabelle, ein Mehrtabellenzugriff wird durch einen Self-Join realisiert. Weitere Details dazu sind auf der Web-Site www.benchmarkresources.com beziehungsweise der erwähnten iX-Ausgabe nachzulesen.

Vor allem die Tatsache, daß SetQuery nur Select-Statements auf numerischen Daten enthält und sich nicht mit Strings, Updates oder Inserts befaßt, führte zu den hier vorgestellten Erweiterungen. Diese machen den Benchmark zwar nicht zum Meßverfahren der Wahl für OLTP-Anwendungen (Online Transaction Processing), aber immerhin gehen Elemente aus diesem Umfeld ein.

Die erste Erweiterung ist eher trivial: das Einlesen der Datensätze wird über SQL-Kommandos (insert) realisiert, die dafür benötigte Zeit gemessen. Nebenbei hat dies den Vorteil größerer Portierbarkeit gegenüber der in den Originaldokumenten vorgeschlagenen Methode, mit datenbankspezifischen Load-Kommandos die Tabelle zu laden.

Zweiter Gegenstand der Messungen ist die Zeit für die Indizierung von 19 der zwanzig Tabellenspalten. Dann folgt der klassische SetQuery im ‘Single User Mode’, das heißt: alle Statements nacheinander. Messung vier startet sämtliche Abfragen des SetQuery im Hintergrund, also quasi parallel, und trägt deswegen den Zusatz ‘Multi User Mode’. Die fünfte Messung besteht aus eigenen, nacheinander durchgeführten Abfragen: select mit Strings als Gegenstand der where-Klausel, update und die im SetQuery nicht verwendeten Aggregatfunktion zur Durchschnittsbildung.

Einen Härtetest für die Belastbarkeit von System und Datenbank stellt der letzte Teil des Benchmarks dar: alle 114 Statements laufen parallel. Dabei werden bis zu 250 Prozesse auf Betriebssystemebene erzeugt, und die Datenbank muß die nötige Anzahl gleichzeitiger Abfragen zulassen.

Vor allem aber geht es im diesem Teil von SQLBench2 um die Granularität der Lock-Verfahren, denn es kommt zu gleichzeitigen Schreibversuchen auf die Daten. Für DBMS, die nur auf Tabellenebene Sperren setzen können, ist deswegen dieser Teil des Benchmarks ungeeignet, da zu viele Updates abgebrochen werden. Dies gilt für die meisten ‘freien’ Datenbanken, aber auch für ältere kommerzielle Systeme wie Microsofts SQL Server 6.5. Zu den veröffentlichten Ergebnissen gehört deswegen nicht nur die Zeit für diese Abfragen, sondern auch die Anzahl der nicht erfolgreichen Update-Statements wegen Dead-Locks. Letzteres impliziert zudem, daß als Locking-Strategie das Prinzip ‘Warten’ gelten muß. Das heißt, kann ein Update-Statement auf den Datensatz nicht zugreifen, soll es auf die Freigabe der Sperre warten, statt mit einer Fehlermeldung abzubrechen.

SQLBench2 besteht aus einer Sammlung von Shell-Scripts und einem C-Programm und ist für Unix und Windows NT konzipiert. Benutzer des Redmonder Betriebssystems benötigen noch eine Bourne-Shell und einige Tools aus der Unix-Welt, etwa CygWin von Cygnus. Bis Redaktionsschluß konnte aber nicht geklärt werden, wie mit diesen Shell-Portierungen die nötige Anzahl an Hintergrundprozessen erzeugt werden kann. Unter Windows ist darum zur Zeit nur der Ablauf der Single-User-Teile des Benchmarks möglich. Das C-Programm generiert die Zufallszahlen und ist sowohl im Quellcode als auch als Binary für Windows NT, Solaris 1/2, HP-UX 9/10 und Linux verfügbar. Weitere Hinweise zur Bedienung liefert das obligatorische Readme, ebenso die Hinweise für die Veröffentlichung eigener Meßergebnisse, erhältlich unter ftp.heise.de/pub/ix/benches.

Mehr Infos

BEFEHLE DES SETQUERY-BENCHMARKS

Q1
select count(*) from bench
where kn = 2
kn Element aus { kseq, k100k, k40k, k10k, k1k, k100, k25, k10, k5, k4, k2 }

Q2A
select count(*) from bench
where k2 = 2 and kn = 3
kn Element aus { kseq, k100k, k40k, k10k, k1k, k100, k25, k10, k5, k4, k2 }

Q2B
select count(*) from bench
where k2 = 2 and not (kn = 3)
kn Element aus { kseq, k100k, k40k, k10k, k1k, k100, k25, k10, k5, k4, k2 }

Q3A
select sum(k1k) from bench
where kseq between 400000 and 500000 and kn = 3
kn Element aus { k100k, k40k, k10k, k1k, k100, k25, k10, k5, k4, k2 }

Q3B
select sum(k1k) from bench
where (kseq between 400000 and 410000)
or (kseq between 420000 and 430000)
or (kseq between 440000 and 450000)
or (kseq between 460000 and 470000)
or (kseq between 480000 and 500000)
and kn = 3
kn Element aus { k100k, k40k, k10k, k1k, k100, k25, k10, k5, k4, k2 }

Q4A
select kseq, k500k from bench
where COND1 and COND2 and COND3
COND1,2,3 Element aus { k2 = 1, k100 > 80, k10k between 2000 and 3000,
k5 = 3, k25 in (11, 19), k4 = 3, k100 < 41, k1k between 850 and 950,
k10 = 7, k25 in (3,4) }

Q4B
Wie Q4A, aber mit fünf Konditionen statt drei

Q5
select kn1,kn2,count(*) from bench
group by kn1,kn2
(kn1,kn2) Element aus { (k2,k100) (k4,k25) (k10,k25) }

Q6A
select count(*) from bench b1, bench b2 where
b1.kn = 49 and b1.k250k = b2.k5
kn Element aus { k100k, k40k, k10k, k1k, k100 }

Q6B
select b1.kseq , b2.kseq from bench b1, bench b2 where
b1.kn = 99
and b1.k250k = b2.k500k
and b2.k25 = 19
kn Element aus { k40k, k10k, k1k, k100 }

Mehr Infos

NEUE BEFEHLE von SQLBENCH2

Q7a
select count(*) from bench where s1 like ’abc%’

Q7b
select count(*) from bench where ks like ’abc%’; ks € { s2 s3 s4 s5 s6 s7 s8 }

Q7c
select count(*) from bench where s2 like ’a%’

Q8a
update bench set k500k = k500k + 1 where k100 between ka and kb
(ka, kb) € {(30, 31), (32, 33), , (46, 47), (48, 49)}

Q8b
update bench set k100 = k100 + 1 where k500k between 30 and 50

Q8c
update bench set k500k = k500k - 1 where k100 between ka and kb
ka, kb: wie Q8A

Q8d
update bench set k100 = k100 - 1 where k500k between 30 and 50

Q9
select avg(k500k) from bench

Q10
select sum(k10) from bench

TABELLE BENCH
Feld Typ Bereich
kseq serial
k500k integer 1- 500 000
k250k integer 1- 250 000
k100k integer 1- 100 000
k40k integer 1- 40 000
k10k integer 1- 10 000
k1k integer 1- 1000
k100 integer 1- 100
k25 integer 1- 25
k10 integer 1- 10
k5 integer 1- 5
k4 integer 1- 4
k2 integer 1- 2
s1 char(8)
s2…s8 char(20)

(js)