Hlavní navigace

Co nového v PostgreSQL 7.4

28. 11. 2003
Doba čtení: 9 minut

Sdílet

Nejlepší, nejkrásnější a nejstarší OpenSource relační SQL databáze je zde po roce v nové verzi. Rok je ve světe počítačů pekelně dlouhá doba, jsou tedy i novinky v release 7.4 pekelné?

Změn je poměrně mnoho. Některé jsou jen přípravou na změny budoucí, jako například na nativní podporu Windows (snad již opravdu v 7.5). Velká část změn se týká efektivnosti a výkonosti.

Změna, ke které nedochází často, je změna protokolu mezi klientem a serverem. Tento protokol nese označení „3.0“. Důležité je, že verze 7.4 umí i starší verzi protokolu 2.0. Jaká verze se zrovna používá, lze na straně klienta zjistit pomocí libpq funkce PQprotocolVer­sion(). Nový protokol je méně ukecaný při startu spojení a umožňuje lepší přenos stavových informací a error kódů. Například přibyla v libpq funkce PQtransaction­Status() nebo PQparameterSta­tus(). Protokol umožňuje přenášet parametry dotazů odděleně od dotazu (viz níže) a přímo do protokolu je integrována podpora pro PREPARE/EXECUTE příkazy. Protokol je na tom i lépe v přenosu binárních dat.

Mezi protokolem a uživatelem vždy stojí nějaká aplikace a její součástí je velmi často již zmiňovaná libpq. Kdo někdy tuto knihovnu zamotával mezi vlákna své multithread aplikace, měl jistě divný pocit, když někde zaslechl, že tato knihovna se honosí podivným označením „thread-ignorant“. Od této verze již lze bez zardění říct, že libpq a aplikace používající ECPG je „fully thread-safe“. Uživatele ECPG by mohlo potěšit i to, že je nyní kompatibilní s Informixem. Vraťme se, ale k libpq, která je podle mého subjektivního dojmu pro programátora jednou z nejpříjemnějších klientských knihoven, co se oblasti SQL týká. Určitě pěkně elegantní je i nová možnost nenamáhat se na straně klienta s plněním dat do řetězce samotného SQL dotazu, ale poslat data a dotaz samostatně a nechat na serveru, ať si oboje spojí. Bude to i rychlejší, protože při parsování dotazu serverem tam nebudou překážet vaše ctěná data. Ta se dostanou do dotazu až při jeho finálním zpracování. Na místo dat se v řetězci dotazu používá znak „$“, například „SELECT * FROM tab WHERE id=$1“. Tuto vlastnost již umí PostgreSQL dlouho, ale šlo ji používat jen uvnitř serveru v SPI funkcích, nyní je tato vlastnost dostupná i pro dotazy ve vašich aplikacích.

Podobnou, ale ještě efektivnější variantou je podpora PREPARE/EXECUTE přímo na úrovni knihovny. Vše je podobné jako u dotazů s $n namísto dat, jen s tím rozdílem, že dotaz si server naparsuje dopředu a dlouhodobě pamatuje a pak je vše jen o zasílání samotných dat serveru.

V souvislosti s možností používat znak dolaru pro přesně definované věci již ho nelze používat jako jméno nějakého operátoru. Pokud tak v nějakém vlastními silami vytvořeném operátoru činíte, tak před migrací na verzi 7.4 jemně poeditujte svůj kód.

Někoho by možná mohla potěšit i plná podpora pro IPv6 a zlepšení výkonu při používání SSL spojení.

Tímto jsme se pomalu dostali až k samotnému serveru. Některé výkonnostní změny jsou ve znamení rázných vylepšení v hashovacích funkcích PostgreSQL. Hash namísto sortu je, máme-li dostatek paměti, používán při zpracovávání GROUP BY. Vnitřně je podporováno přímo hash funkcemi více datových typů, což vede ke kvalitnějším výsledkům. Nově je podporován pro hash join i multikey (více sloupečků), což by mělo zlepšit výkonost některých složitějších dotazů.

Zrychlení a některých optimalizací se dočkaly dotazy s operátorem IN, který používá také zmiňované hash funkce. Optimalizátor uvnitř PostgreSQL se snaží dotazy typu „a.x IN( SELECT b.x FROM…)“ přepsat a vykonat jako daleko jednodušší klasický join „a.x = b.z“. Podobně i z dotazu typu „WHERE a.x = b.y AND b.y = 27“ optimalizátor pozná, že lze tvrdit, že „a.x = 27“. Urychlení doznalo i použití IN v případě konstantních dat, tedy „col IN (const, const, const, …)“.

To, proč má řada uživatelů ráda PostgreSQL, je mimo jiné možnost definovat vlastní funkce. Tentokrát se sice v této oblasti neudálo nic tak mimořádného jako ve verzi předchozí, ale zajímavou novinkou pro jednoduché SQL funkce je „function-inlining“, kdy jsou tyto funkce přímo integrovány za chodu do SQL dotazu (něco jako makra) a nejsou samostatně zpracovávány relativně složitým systémem, který se stará o volání ostatních funkcí.

Určitě zajímavým rozšířením je podpora „polymorphic“ SQL funkcí. Jedná se o funkce, které jsou poměrně svobodomyslné ve vztahu k datovým typům svých parametrům, případně k datům, která vracejí. Stačí k tomu kouzelné slůvko „anyelement“ nebo „anyarray“. Například:

CREATE FUNCTION mygr(anyelement, anyelement) RETURNS boolean AS 'SELECT
$1 > $2;' LANGUAGE 'SQL';

# SELECT mygr(5, 4);
  mygr
 ------
   t

# SELECT mygr(now(), '1900-10-12');
  mygr
 ------
   t 

Asi každý, kdo se snažil něco složitějšího hledat v textech, uvítal možnosti obsažené v regulárních výrazech. Podobně jako PostgreSQL i tzv. regex mají svůj prapůvod na univerzitě v Berkeley. Jejich původní autor Henry Spencer již před několika lety vytvořil novou verzi pro jazyk Tcl. Nyní je tato výkonnější verze i součástí PostgreSQL.

Snad se nemýlím, ale READ-ONLY transakce jsou tím posledním, co je celkem běžné u transakčních databází a zatím nebylo podporováno u PostgreSQL. Od verze 7.4 lze tedy v příkazu SET TRANSACTION ISOLATION LEVEL definovat i READ ONLY typ transakce.

Pokud rádi mažete data, jistě máte v malíčku dotaz TRUNCATE. Nyní se již nemusíte tak moc bát a můžete do toho mazání jít na plno, protože v rámci transakce to, co TRUNCATE smaže, lze zase vrátit. Říká se tomu, že příkaz je „transaction-safe“.

Při složitější práci s daty na straně klienta se často používají tzv. kursory ukazující do dat vytvořených SQL dotazem na straně serveru. S touto vlastností související příkazy FETCH a MOVE, které jsou nyní rozšířeny o parametry „FIRST, LAST, ABSOLUTE x, RELATIVE x“ tak, aby PostgreSQL byl více kompatibilní s SQL standardem. Daleko zajímavějším zlepšením je však možnost existence deklarovaných kursorů mimo transakce, a to pomocí parametru WITH HOLD v příkaze DECLARE.

Ruka standardizátorova (ten, jenž se snaží dotlačit PostgreSQL k co největší kompatibilitě s SQL standardy, a ten, jehož ruka je pekně ohlodaná v jiné nejmenované volně šiřitelné SQL databázi) se dotkla mimo jiné i příkazu CREATE SEQUENCE. Byl přidán i příkaz ALTER SEQUENCE pro pohodlnější úpravy minima, maxima, inkrementace apod.

Příkazem EXPLAIN nově taktéž chápe, že součástí definice kursoru v DECLARE je SQL dotaz, a tak dokáže pro tento dotaz svým neodolatelným způsobem ukázat, co si o jeho zpracování myslí. Stačí před definici kursoru napsat magické EXPLAIN. Podobně to po novu umí i pro dotaz uložený a naparsovaný v cache serveru pomocí PREPARE, například „EXPLAIN EXECUTE jméno_dotazu;“

Jistě potěší a nenaštve drobnost, jakou je funkce md5(), a to přímo ve standardním PostgreSQL bez nutnosti něco dalšího hledat v doplňcích k PostgreSQL (tzv. contrib).

Rozšíření se dočkal i příkaz GRANT o „WITH GRANT OPTION“ parametr, který, je-li uveden, tak ten, komu je toto právo dáno, může k objektu, kterého se to týká, rozdávat práva dalším uživatelům. Vlastně se stává takovým malým administrátorem toho svého objektu (například tabulky). Snad mne paměť neklamem v Oracle se to samé jmenuje „WITH ADMIN OPTION“.

Již v předešlé verzi bylo možné vytvářet tabulky bez interního číslování řádek pomocí OID. Toto je zajímavé pro velké tabulky, kde ušetříte 4 byte na řádek a trošinku odlehčíte systému s generováním nových OID a prací s nimi. Nově lze OID odstranit z již existujících tabulek pomocí ALTER TABLE … WITHOUT OIDS.

Dědičnost u tabulek má PostgreSQL již dlouho. Podobnou vlastností je možnost definovat tabulku s parametrem „LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ]“, kdy jsou definice sloupců převzaty (včetně nebo bez DEFAULT hodnot) z rodičovské tabulky. Oproti dědičnosti definované pomocí INHERITS jsou v tomto případě tabulky na sobě nezávislé a jedná se čistě o záležitost použitou při tvorbě nové tabulky.

I další novinka se týká tabulek. V tomto případě dočasných (TEMPORARY | TEMP). Dosud byla dočasná tabulka odstraněna při ukončení session (ukončení spojení server/klient). Nyní lze dočasnost definovat s ohledem na transakce a definovat i to, co se má s tabulkou stát – tedy má-li být smazána, nebo jen smazat řádky v tabulce, a nebo nic (default). A to vše pomocí ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP }.

Podobně, jako tabulka může být vytvořena dle nějakého selectu pomocí „CREATE TABLE tab2 AS SELECT * FROM tab1“, tak nově může být podkladem pro vytvoření tabulky i parsovaný a uložený dotaz, a to pomocí „CREATE TABLE tab2 AS EXECUTE jméno“.

A poslední zajímavost ohledně tabulek. PostgreSQL již nebude mít problém, pokud vaše tabulky budou mít nula sloupců.

Určitě zajímavá je možnost provádět „UPDATE … SET col = DEFAULT“, který vede k tomu, že data sloupce jsou nastavena na default hodnotu definovanou při definici tabulky.

Konečně mohou být také hodnoty pro LIMIT a OFFSET v SELECTu výsledkem nějakého výrazu.

Pole jako datový typ byla jedna z věcí, které se mi, ani nevím proč, líbila při prvním setkání s PostgreSQL. Od té doby jsem je použil jen jednou, a to ještě dost zbytečně. S novými rozšířeními možná najdou své další a o poznání věrnější uživatele. Důležitá je celá skupina operátorů a funkcí umožnující vyhledávat dle prvku pole, přidávat do pole nové elementy, spojovat pole pomocí standardního concatenate operátoru „||“ (ne, tohle není žádné „or“…), indexovat sloupce s poli a používat tyto sloupce v ORDER BY a DISTINCT.

Byl přepsán poměrně náročný datový typ numeric, který dovoluje používat čísla bez omezení na jejich velikost. Lze tak předejít nežádoucímu zaokrouhlování apod. Náročnost by měla být menší.

Příznivci fulltext indexování textů najdou v contribu k PostgreSQL novou verzi modulu, který právě toto umí.

Každá session (spojení server/klient) je v PostgreSQL obsluhována jedním samostatným procesem, který se startuje při zahájení a končí při ukončení session. To pochopitelně stojí nějaké systémové prostředky, a například pokud rozšiřujete PostgreSQL o vlastní moduly, znamená to vždy a znova při startu jejich nové načtení. Tomu lze od 7.4 předejít použitím „preload_libraries“ u hlavního postmaster procesu. Moduly jsou pak děděny i samostatnými procesy, co obsluhují spojení.

Ne každý se sžil s tím, jak velkoryse PostgreSQL dokáže plnit disky. Pomoci by mohla lepší implementace příkazu VACUUM nad nepoužívanými daty indexů, kde již nepoužívané místo by mělo být možné znovu efektivně použít. Pokud si nainstalujete i prográmky z contribu PostgreSQL, najdete utilitku „pg_autovacuum“, která je schopná běžet automaticky jako samostatný démon, monitorovat používání databáze, a je-li to třeba, aplikovat příkaz VACUUM, a to až ve vteřinových intervalech. Monitorování se děje na základě statistik v systémových tabulkách. Tyto statistiky musíte povolit v postgresql.conf. Pokud opravdu často svá data měníte, vřele vám tuto utilitku doporučuji. PostgreSQL si pak udržuje stabilní výkona bez sklonu k zpomalování.

Pod Linuxem by mělo být možné kompilovat PostgreSQL pomocí Intel kompilátoru a vše by mělo, tak jak má, chodit i s procesorem Itanium, případně od konkurence pocházejícím AMD Opteronem.

UX DAy - tip 2

Nevím, kolik je mezi námi uživatelů s kombinací Macu a PostgreSQL, ale určitě se najdou ti, kteří používají různé nadstavby DOSu (jako různá Windows). Pro obě skupiny uživatelů má PostgreSQL pochopení a bude chápat jejich konce řádek v příkazu COPY, i když tyto konce nekončí na staré dobré „\n“.

A když už jsme u konců, tak bude dobré ukončit i tento článek a nechat čtenáře, ať si sám nový PostgreSQL 7.4 prohlédne a vyzkouší i to, co se do článku nevešlo. A je toho hodně, protože oficiální seznam změn má cca 750 řádek.

Byl pro vás článek přínosný?