Novinky 2006 (PostgreSQL 8.2)

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

Rok intenzivního vývoje PostgreSQL vývojáři uzavřeli uvolněním bety verze 8.2. Na plnou verzi si ještě budeme muset počkat do vánoc, nicméně už nyní si můžeme vytvořit určitou představu o této další verzi. 8.2 neobsahuje žádný super trhák jako předchozí dvě verze. Asi nejočekávanější podpora bitmapových indexů a editovatelný pohledů chybí. Neznamená to ovšem, že by se nevyplatil přechod na tuto verzi. Tato verze je opět znatelně výkonnější než předchozí, a navíc můžeme modifikací parametru FILLFACTOR ovlivnit rychlost provádění operací UPDATE a DELETE. Znatelně (až o 30%) je rychlejší COPY.

V nové verzi můžeme nastavit i míru obsazení (fillfactor) datových stránek. Tato hodnota udává na kolik procent se bude využívat datová stránka pro nové záznamy, a kolik prostoru zbude na datové stránce pro případné aktualizované řádky příkazy UPDATE nebo DELETE. Fillfactor se udává v procentech mezi 10..100. Čím menší je, tím je větší pravděpodobnost, že aktualizovaná kopie řádku zůstane na stejné stránce jako originál, což je, z hlediska přístupu, mnohem efektivnější než její umístění na jiné stránce. Díky tomu, v některých případech nebudeme, nuceni tak často spouštět VACUUM tabulky.

CREATE TABLE FOO(...) WITH (FILLFACTOR = 80);

Nalezení optimální hodnoty bude asi dost velkou alchymií. Zkusmo jsem nastavil 50% u intenzivně modifikovaných tabulek používaných v pgbenchi a překvapivě jsem výkon PostgreSQL výrazně degradoval. Na jednu stranu se zvýší rychlost dotazů na modifikované řádky, na druhou stranu se zvýší počet datových stránek a tím je sekvenční čtení pomalejší. Jeden z důvodů proč nepoužívat pg_autovacuum je jeho závislost na provozních statistikách. Ty mohly v předchozích verzích mít až 20% režii při plném zatížení, což už leckde mohlo působit problémy. V 8.2 je režie provozních statistik také nezanedbatelná, je ale poloviční (max. 10%). Výchozí konfigurace PostgreSQL8.2 je o něco realističtější, co se týče přednastavených parametrů správy paměti. U minulých verzích bylo zvykem tyto konfigurační parametry automaticky několika násobně zvětšit. Pro úplnost uvedu výkon v pgbenchi posledních pěti verzí. Konfigurace starších verzí je upravena tak, aby odpovídala výchozí konfiguraci verze 8.2.

Verze 7.3.15 7.4.13 8.0.8 8.1.4 8.2.beta1
tps 311 340 334 398 423

Tato čísla berte orientačně. Pgbench (TPC-B) je spíš test hrubé síly, neukáže např. sofistikovanější použití indexů nebo propracovanější optimalizaci prováděcího plánu. Měřeno na průměrném notebooku P(M)1.6G 512 MB RAM, Fedora6. Zajímavější by určitě byl test na víceprocesorovém serveru, kde by měl být zřetelnější odstup verzí 8.x od verzí 7.x.

Co se mi na 8.2 nejvíc líbí? Jasného favorita nemám. Potěší opět o něco inteligentnější plánování dotazů, zrychlení řazení. Všiml jsem si znatelného zrychlení sekvenčního čteni. Snad nejvíc mi ulehčí život jedna opravdu malá drobnost a to podpora NULL v polích (jsem programátor). Teď, kdy jsou domény plně podporovány v PL/pgSQL, začínám uvažovat o jejich intenzivnějším používání. Ušetřím si práci s voláním ASSERT procedur.

CREATE DOMAIN pos_int int CHECK (VALUE >=0);
CREATE OR REPLASE FUNCTION test (p pos_int) REURNS pos_int AS $$
DECLARE v pos_int;
BEGIN v := p - 1;
  RETURN v - 1;
END; $$ LANGUAGE plpgsql IMMUTABLE;

Další drobností, která potěší je zarovnávání intervalů:

justify_interval(interval '3 days 52 hours 3 minutes 2 seconds') ->5 days 04:03:02

Pravidelně dochází k inovacím psql. Zobrazení opravdu velké tabulky mohlo zhavarovat nedostatkem paměti. Tomu lze předejít aktivací čtení výsledku kurzorem. Psql lépe zobrazuje sloupce obsahující víceřádkový text. Víceřádkové příkazy se v historii ukládají jako jeden blok a tudíž se s historií mnohem lépe pracuje, resp. teprve teď lze pracovat s více řádkovými příkazy. V systémových pohledech nyní dohledáme čas naposledy provedených operací VACUUM a ANALYZE. Seznam funkcí zobrazuje návratový typ a seznam argumentů včetně jejich názvu a typu:

postgres=# \df test
                           List of functions
 Schema | Name | Result data type  |        Argument data types
--------+------+-------------------+------------------------------------
 public | test | character varying | a integer, OUT b character varying
(1 row)

Došlo k nahrazení int8 za int4 všude tam, kde již nestačil rozsah int4 (LIMIT, OFFSET). PostgreSQL nyní umožňuje definovat vlastní více parametrické agregační funkce. S tím souvisí i podpora nových SQL2003 agregačních binárních funkcí (corr, regr_sxy, ...). Většina stávajících instalačních skriptů trpí hlášením falešných chyb, když dojde k pokusu o odstranění dosud neexistujícího objektu. Tento problém propříště řeší rozšíření příkazu DROP o frázi IF EXISTS. Příkaz TRUNCATE byl rozšířen o příznak CASCADE - efektivní způsob jak si totálně vyčistit databázi.Byla odstraněna chyba u ILIKE, která jej nedovolovala použít u více bajtových kódování.

Uživatele windows a hlavně odpůrce překladače gcc jistě potěší, že PostgreSQL lze přeložit v Microsoft Visual Studiu. Kromě snad lepšího výkonu, lze hlavně používat prostředí Visual Studia. Pomalu ale jistě port na WIN NT platformu dotahuje ve spolehlivosti a výkonu svůj UNIXový originál. Nad výdělkem spláčou uživatelé QNX a BEOSu. Tyto systémy už nejsou podporovány. Nativní podpora LDAPu by měla zpříjemnit život dba, kteří prohání PostgreSQL na WinNT. Účinnější tunning na Sunech by měl být možný díky vestavěné podpoře DTrace.

Joe Conway a Tom Lane navrhli tzv. vícenásobný insert [multi value insert] . Díky obecně pojatému řešení je nyní podporován také tzv. table value constructor.:

postgres=# select a from (values(1),(2)) a(a);
 a
---
 1
 2
(2 rows)

Multi value insert nemá nahradit příkaz COPY TO. Na to je pomalejší a náročnější na paměť. Jeho smysl je v zjednodušení importů z databází, které generují dump v tomto formátu (např. MySQL). Pokud je mi známo, tak je PostgreSQL jediná o.s. databáze, která table value constructor, dle SQL2003, podporuje.

Jasnou bombou je rozšíření DML příkazů o část RETURNING. Syntaxe je kompatibilní s Oracle. O co jde? Pokud v těchto příkazech používáme implicitní hodnoty nebo výrazy, tak vlastně "neznáme" přesně výsledek. Dost často, po těchto příkazech, následuje dotaz, kde si požadované hodnoty zjistíme (např. PK ze sloupců typu SERIAL). Fráze RETURNING modifikuje příkazy INSERT, UPDATE, A DELETE tak, že vrací tabulku obsahující nové hodnoty, nebo libovolný výraz. CREATE TABLE users(id SERIAL PRIMARY KEY, inserted timestamp DEFAULT CURRENT_TIMESTAMP, ... );

--8.2.
INSERT INTO users (name, surname, ....) VALUES(...) RETURNING *;
--8.1
INSERT INTO users (name, surname, ....) VALUES(...);
SELECT id, inserted, name, surname WHERE id = lastval();

Pro tyto příkazy nechybí podpora v PL/pgSQL:

CREATE OR REPLACE FUNCTION testa() RETURNS VOID AS $$
DECLARE _a integer; _b integer; _c integer;
BEGIN
  FOR _a, _b, _c IN INSERT INTO foo VALUES (10,20,30),(10,11,12) LOOP
    RAISE NOTICE '% % %', _a, _b, _c;
  END LOOP;
END;
$$ LANGUAGE plpgsql;

Bohužel, ještě nelze napsat SQL příkaz jako je např.:

INSERT INTO archive SELECT * FROM (DELETE FROM dt RETURNING *)

Spolu s PostgreSQL bylo dokončeno nebo vylepšeno několik rozšíření z adresáře contrib nebo z repozitáře pgfoundry. Namátkou uvedu některá z nich: tsearch2 (fulltext) podporuje UTF8 a mělo by být znatelně rychlejší a také umožňuje použít slovníky z Open Office, pgstattuple (monitoring podílu mrtvých záznamů v tabulce), pgcrypto(kryptografické funkce), orafunc (implementace několika desítek funkcí rdbms Oracle).

Masivní změny se dočkal PL/Python. Podpora Pythonu je nyní na stejné, ne-li vyšší, úrovni jako je podpora Perlu. V Pythonu můžeme psát funkce používající složené typy, vracet tabulky, můžeme používat pojmenované parametry. Java není podporována přímo v hlavním stromě, takže defakto nemá s betou nic společného, nicméně se podpora Javy vyspěla tak, že v Javě můžeme navrhovat vlastní datové typy. Je to jediný programovací jazyk vyjma C, kde je to možné. Je zpřístupněno SPI rozhraní prostřednictvím upraveného JDBC driveru. Vše respektuje ANSI SQL 2003 SQLJ (takže teoreticky by uložené procedury měly být kompatibilní s Oracle, DB2, atd).

package foo.fee;
import java.util.Iterator;

public class Bar
{
    public static Iterator getNames()
    {
        ArrayList names = new ArrayList();
        names.add("Lisa");
        names.add("Bob");
        names.add("Bill");
        names.add("Sally");
        return names.iterator();
    }
}

CREATE FUNCTION javatest.getNames()
  RETURNS SETOF varchar
  AS 'foo.fee.Bar.getNames'
  IMMUTABLE LANGUAGE java;

Nelze si nevšimnout "komercionalizace" vývoje PostgreSQL. Po neúspěšném pokusu Great Bridge se o totéž pokouší EnterpriseDB, která v současnosti zaměstnává většinu core vývojářů. Pár ostatních je soustředěn v RedHatu, GreenPlumu, SkyPe. Skutečně nezávislých vývojářů (např. z univerzit) zůstává jen několik. Ostatně není se čemu divit. Tak rozsáhlý a kvalitní software se již nedá dělat na půl úvazku. Svůj podíl na úspěchu PostgreSQL se snaží získat také SUN, který buduje profesionální support týmy a spolu s dalšími společnostmi nabízí komerční podporu.

Zdaleka se však nepodařilo splnit všechna přání uživatelů. Bodově uvedu funkce na které si budeme počkat do dalších verzí: bitmapové indexy, editovatelné pohledy, rekurzivní a analytické dotazy, SQL příkaz MERGE, podpora collations, podpora SQL/XML.

Ani zdaleka jsem nevyjmenoval všechny novinky, které si můžete v betě PostgreSQL nyní vyzkoušet. A těm, které jsem uvedl, jsem určitě nevěnoval tolik prostoru, kolik by si zasloužily. Už beta je stabilní, tak jak je u PostgreSQL zvykem, a nevidím, žádný důvod, proč bych Vám ji nemohl doporučit k otestování.


Související články: