Příprava našeho TPC-B testu databází

Dnešní díl bude věnován metodice jak jsme testovali databáze v TPC-B a dostane se i na srovnání kvality JDBC driverů.

25.10.2010 15:00 | Radim Kolář | přečteno 5969×

Vypovídající hodnota testů

TPC-B test simuluje především dávkové zpracování dat. Je navržen tak aby co nejvíce stresoval databázi, protože používá prakticky samé (80%) zápisové operace. V reálných interaktivních aplikacích, kupříkladu ve webovkách, se nezapisuje do databáze moc často. Většinou je počet zápisů jen okolo 10%. Pro simulaci webovek by proto byl lepší TPC-C test který má jen 17% zápisů.

Metodika testování

Testoval jsem tyto volně dostupné databáze: PostgreSQL 8.3, Oracle XE 10R2, DB2 Express 9.7.2, Apache Derby (Cloudscape) 10.3 a 10.6, MySQL 5.0. Původně jsem měl v plánu testovat MySQL 5.1, ale subsystém InnoDB se zakousával během nahrávání testovacích dat a MYISAM se nedalo použít protože není ACID kompatibilní. FirebirdSQL jsem kvůli jejímu malému rozšíření mezi uživateli vynechal úplně.

Testování probíhalo na Pentium Dual Core E2200, 2.2GHz s 2GB DDR2 335Mhz, 1x SATA hard disk 7200 RPM. Jako operační systém byl zvolen Windows XP SP3 z důvodu rychlého a snadného nainstalování databází. Windows 7 byl nekompatibilní s DB2 a Oracle se mi do Ubuntu linuxu instalovat nechtělo, protože to by vyžadovalo editaci konfiguračních scriptů. Šlo mi především o vzájemné porovnání databází ne o dosažení co nejlepšího výsledku a tak jsem tam ty Windows nechal.

Opět jsem si ověřil že 2GB RAM je pro Oracle málo a proto jeho hodnoty berte s rezervou. Podle dokumentace Oraclu XE by ovšem mělo stačit 256MB a doporučováno je 512MB. To vypadá velmi komicky zvlášť když si uvědomíme že default SGA má 900MB. Manuály Oraclu proto neberte nikdy vážně. Pokud se chcete naučit dobře Oracle tak jsou knihy, co napsali lidé s praktickými znalostmi databáze, nezbytně nutné. Můj na věc Oracle dokumentace je že za ty peníze co Oracle stojí by se snad měl někdo schopný najít a ty manuály napsal pořádně. Vedení dokumentačního oddělení to ovšem stejně nevidí, podle jejich logiky komu se naše manuály nelíbí tak ať si koupí knížku, na trhu je jich dostatek.

Kvalita JDBC driverů

Kromě vlastních databází mne také zajímala kvalita JDBC driverů. Na JDBC driverech záleží protože JDBC je na první až druhé pozici nejpoužívanějších databázových rozhraní. Kvalita JDBC driveru se skládá ze dvou bodů: kompatibilita s JDBC standardem a efektivita. Kompatibilita s JDBC standardem je jednoduchá: Je v něm definováno jaké funkce musí driver poskytovat, co tyto funkce mají dělat, jaké hodnoty vracet a jaké vyjímky signalizovat. Pokud jde o efektivitu tak dobrý JDBC driver musí maximálně využívat schopností efektivně zpracovávat data dané databáze.

DB2 a Oracle

Komerční databáze Oracle a DB2 měli vynikající JDBC drivery. Ze zkušenosti vím, že Oracle JDBC driver má sice občas nějaké chyby, ale support Oraclu tyto chyby rychle řeší a dostanete rychle k dispozici jeho opravenou verzi. V DB2 JDBC driveru je chyb výrazně méně. Oba dva drivery jsou velmi efektivní co se týče rychlosti zpracování dat. Není ostatně divu, komerční databáze s nekvalitním JDBC driverem by moc velký úspěch neslavila. Komerční software je totiž existenčně závislý na spokojenosti svých uživatelů - nespokojený zákazník si příště koupí jinde nebo sáhne po stále více oblíbenějším open source řešení.

PostgreSQL

Co se týče PostgreSQL JDBC driveru, tak k tomu mám řadu výhrad. Základní je, že situace ohledně jeho kvality stagnuje už asi pět let a není tu žádná známka toho, že by se na jeho dlouho přetrvávajících nedostatcích něco směrem do budoucna dělalo. Je to velká škoda, protože PostgreSQL je rozhodně kvalitní produkt zejména s přihlédnutím k jeho nulové ceně a absence kvalitního JDBC driveru je velkým nedostatkem.

Nedostatky PostgreSQL JDBC driveru jsou obecně známé, většinu jich najdete uvedenou v jeho TODO listu. Pokud se jedná o kompatibilitu se standardem tak není podporována práce s metadaty, podpora PostgreSQL kurzorů (všechny kurzory jsou emulovány pomocí SELECTu jako insensitive) a důležitá metoda getGeneratedKeys(). Pokud se jedná o efektivitu tak největším problémem je absence podpory prepared statementů, nepodporování batch transakcí a nemožnost načítání result setu přes kurzor. Absence nepodpory prepared statementů a batch transakcí si obvykle hned nevšimnete - menší výkon se svede na to že je to prostě ta pomalá Java.

Horší je to s načítáním celého result setu do paměti. Pokud SELECT z databáze vrátí větší počet řádek (kupříkladu statisíce) tak program zhavaruje na nedostatek paměti. Řešemím které vám autor ochotně poradí je upravit aplikaci tak aby používala kursory (ale ne JDBC kursory ty jsou jen emulované) Postgresu pomocí Statement.executeUpdate("DECLARE c1 CURSOR FOR SELECT ..."). Tímto sice problém s pamětí odstraníte, ale zase ztratíte kompatibilitu s jinými databázemi. Také tímto nepomůžete profesionálním nástrojům pro tvorbu reportů pokud nepodporují speciálně PostgreSQL. Logické řešení by bylo opravit JDBC driver, to se ale autorovi nechce, protože vývoj driveru je jen jeho koníček a tento problém ho nezajímá natolik aby do něj investoval svůj volný čas.

MySQL

S MySQL pracuji naštěstí jen vyjímečně a tak jsem předpokládal že jelikož si na Internetu lidé houfně nestěžují na její JDBC driver tak bude určitě v pořádku. Podcenil jsem ovšem uživatele MySQL které mají velmi nízké požadavky na kvalitu. JDBC driver MySQL je nejhorší JDBC dílo co jsem doposud během své praxe potkal.

První překvapení bylo, že zavolání funkce commit v autocommit módu vyhazuje exception. Commit v autocommit modu sice není potřeba, ale jeho zavolání by nemělo skončit vyjímkou a přerušením nasledného vykonávání SQL příkazů v programu.

Dalším velkým problémem, ačkoliv nesouvisející přímo s TPC-B protože se v něm typ CHARACTER nepoužívá, byla práce se znakovými sadami. Nepodařilo se mi rozchodit aby Java zobrazovala korektně ne Latin1 znaky z databáze pokud nebyla databáze uložená v UTF-8.

Nejhorší byla ale neskutečná pomalost driveru. Nepomohlo ani použití prepared statementů, ani použití batch transakcí. Batch transakce driver jen emuluje protože je MySQL neumí a zda umí mapovat prepared statementy z Javy na prepared statementy serveru se mi nedpodařilo z dokumentace zjistit.

Apache Derby

Apache Derby je embedded databází a žádný JDBC driver k ní není potřeba protože JDBC rozhraní je přímo její součástí. Pokud Derby používáme v klient/server režimu tak Derby komunikuje podobně jako IBM DB2 a Informix protokolem DRDA, takže je možné k ní použít kromě jejího JDBC driveru derbyclient.jar i drivery těchto komerčních databází.

Nahrávání dat

Měření za jak dlouho se do databáze nahraje TPC-B se scale faktorem 10 (tedy něco málo přes jeden milión řádků a 100MB) bylo nesoutěžní disciplínou. Čísla jsou ale zajímavá:

DatabázeČas
PostgreSQL 8.3128 sekund
DB2 9.734 sekund
MySQL 5.07 minut 45 sekund
Derby 10.33 minuty 16 sekund

Údaje pro Oracle v tabulce chybí, ale co si vzpomínám tak byl asi o 10 sekund rychlejší než DB2 a zaujal tak první místo. Oraclu a DB2 by se dokázal přiblížit i Postgres, kdyby měl lepší JDBC driver. Naopak MySQL úplně výkonově propadlo, jeho JDBC driver je opravdu velice neefektivní a na jeho neefektivitu si často lidé stěžují zejména v kombinaci s ORM produktem EclipseLink. Apache Derby je sice všeobecně považováno za pomalou databázi, ale když vezmeme v úvahu že je především určené pro malé objemy dat a menší zátěž tak nedopadlo zase tak špatně. U Derby mají totiž prioritu funkce, ne výkon.

Online verze článku: http://www.linuxsoft.cz/article.php?id_article=1769