PostgreSQL 8.3 Pavel Stěhule Department of Mapping and Cartography, Faculty of Civil Engineering Czech Technical University in Prague stehule kix.fsv.cvut.cz Kĺıčová slova: Database systems, Open Source Abstrakt Práce na Open Source databáźıch pokračuj́ı nezadržitelným tempem. Vývojáři se muśı vy- rovnat s rostoućımi požadavky uživatel̊u na objem dat ukládaných do databáźı, na náročněǰśı požadavky na odezvu atd. Zat́ım nedostǐznou metou je implementace celého standardu ANSI SQL 200x. Všechny databáze z velké trojky (Firebird, MySQL a PostgreSQL) použ́ıvaj́ı mul- tigeneračńı architekturu, cenově orientované hledáńı optimálńıho prováděćıho plánu, write ahead log atd. MySQL se profiluje jako SQL databáze schopná použ́ıvat specializované da- tabázové backendy schopné maximálńı efektivity pro určité konkrétńı prostřed́ı. PostgreSQL je široce použitelná databáze, těž́ıćı z vynikaj́ıćı stability, s perfektńı rozšiřitelnost́ı a kom- fortńım prostřed́ım. Konečně Firebird je vynikaj́ıćı embeded databáze, která se osvědčuje v tiśıćıch instalaćıch na desktopech. Podle p̊uvodńıho plánu mělo doj́ıt k uvolněńı verze 8.3 koncem léta – mělo j́ıt o verzi obsahuj́ıćı patche dokončené pro 8.2, ale v té době nedostatečně otestované. Nakonec se ukázalo, že ty nejd̊uležitěǰśı patche je třeba dopracovat. Jednalo se o tak atraktivńı vlastnosti, že se rozhodlo s vydáńım nové verze počkat. 8.3 obsahuje integrovaný fulltext, podporu opožděného potvr- zováńı (asynchronńı commit), synchronizované sekvenčńı čteńı datových soubor̊u, úsporněǰśı ukládáńı dynamických datových typ̊u (kraťśıch 256byte), HOT updates a sofistikovaněǰśı aktu- alizaci index̊u (hot indexes). Z patch̊u připravených pro 8.2 se v 8.3 neobjev́ı podpora bitma- pových index̊u a podpora aktualizovatelných pohled̊u. P̊uvodńı řešeńı založené na pravidlech (rules) bylo př́ılǐs komplikované. 8.3 obsahuje podporu aktualizovatelných kurzor̊u, a je docela dobře možné, že aktualizovatelné pohledy budou ve verzi 8.4 implementovány právě s pomoćı této tř́ıdy kurzor̊u. Vývoj pokračuje implementaćı daľśıch modul̊u SQL. Ve verzi 8.3 je to konkrétně SQL/XML (rozš́ıřeńı ANSI SQL), která umožňuje operace s XML dokumenty př́ımo v databázi a zjed- nodušuje generováńı XML dokument̊u. Zásadńı (interńı) změnou je zkráceńı hlavičky řádku z 28 bajt̊u na 24 bajt̊u. Daľśı změnou, která by měla vést k minimalizaci velikosti uložených dat je diverzifikace typu varlena. Tento typ se v PostgreSQL použ́ıvá pro serializaci hodnot všech typ̊u s variabilńı délkou. Trochu připomı́ná string v Pascalu. Prvńı byty nesou informaci o délce, daľśı nesou obsah. Starš́ı verze PostgreSQL znaly jen typ varlena s 4byte informaćı o Geinformatics FCE CTU 2007 91 PostgreSQL 8.3 délce. 8.3 podporuje také typ varlena s 1byte záhlav́ım. Úspora by se měla projevit hlavně u typu NUMERIC a krátkých řetězc̊u. K překladu PostgreSQL lze poč́ınaje touto verźı použ́ıt jak gcc, MINGW tak Microsoft Visual C++ (na platformě Microsoft Windows). Integrace TSearch2 Integrace TSearch2 do jádra PostgreSQL je výsledkem dlouholetého úsiĺı Olega Bartunova a Teodora Sigaeva. Dı́ky integraci se zjednoduš́ı konfigurace fulltextu a pro určité jazyky (pro které existuje podpora v projektu Snowball) lze fulltext použ́ıvat hned po instalaci databáze. Čeština bohužel mezi tyto jazyky nepatř́ı – je potřeba provést několik daľśıch operaćı. Předně převést Open Office slovńıky do kódováńı UTF8 a zkoṕırovat je do př́ıslušného podadresáře PostgreSQL. Dále zaregistrovat slovńık a provést tzv. konfiguraci. Kromě konfigurace jsou rozd́ıly mezi integrovaným fulltextem a TSearch2 (z verze 8.2) sṕı̌se kosmetické. CREATE TEXT SEARCH DICTIONARY cspell1( template=ispell, dictfile = czech, afffile=czech, stopwords=czech); CREATE TEXT SEARCH CONFIGURATION cs (copy=english); ALTER TEXT SEARCH CONFIGURATION cs ALTER MAPPING FOR word, lword WITH cspell, simple; postgres=# select * from ts_debug(’cs’,’Přı́liš žlut’oučký kůň se napil žluté vody’); Alias | Description | Token | Dictionaries | Lexized token -------+---------------+-----------+-----------------+--------------------- word | Word | Přı́liš | {cspell,simple} | cspell: {přı́liš} blank | Space symbols | | {} | word | Word | žlut’oučký | {cspell,simple} | cspell: {žlut’oučký} blank | Space symbols | | {} | word | Word | kůň | {cspell,simple} | cspell: {kůň} blank | Space symbols | | {} | lword | Latin word | se | {cspell,simple} | cspell: {} blank | Space symbols | | {} | lword | Latin word | napil | {cspell,simple} | cspell: {napı́t} blank | Space symbols | | {} | word | Word | žluté | {cspell,simple} | cspell: {žlutý} blank | Space symbols | | {} | lword | Latin word | vody | {cspell,simple} | cspell: {voda} (13 rows) Podporu fulltextu nad konkrétńım sloupcem můžeme aktivovat např. vytvořeńım funkcionál- ńıho GIN indexu. CREATE INDEX data_poznamka_ftx ON data USING gin(to_tsvector(’cs’, poznamka)) a vyhledávat operátorem @@ (fulltextové vyhledáváńı) SELECT * FROM data WHERE to_tsvector(’cs’,poznamka) @@ to_tsquery(’žlutá & voda’) Podpora SQL/XML Zásadně se změnila podpora XML. To co v předchoźıch verźıch se neohrabaně řešilo přes doplňky se nyńı dostalo př́ımo do jádra. Jednak jsou k dispozici funkce generuj́ıćı XML (xmlelement, xmlforest, ...) jednak jsou tu funkce mapuj́ıćı obsah tabulky do XML. Výsledkem může být XML schéma (použitelné pro validaci nebo pro přenos definice tabulky), XML dokument s integrovaným schématem, nebo samotný XML dokument. Jelikož je výstupńı Geinformatics FCE CTU 2007 92 PostgreSQL 8.3 formát standardizován v SQL/XML, neměl by být přenos těchto tabulek problémem (mezi těmi databázemi, které SQL/XML podporuj́ı). pavel=# create table a(a date, b varchar(10)); CREATE TABLE pavel=# insert into a values(current_date, ’něco’),(current_date+1, NULL); INSERT 0 2 pavel=# select table_to_xml_and_xmlschema(’a’, true, false, ’’); table_to_xml_and_xmlschema ------------------------------------------------------------------------------------------------ 2007-02-19 něco 2007-02-20 Stejného výsledku dosáhneme pomoćı funkćı generuj́ıćıch XML. Jejich použit́ı je univerzálněǰśı, a o trochu komplikovaněǰśı: pavel=# SELECT xmlelement(name a, xmlagg( xmlelement(name row, xmlforest(a,b)))) FROM a; xmlelement ---------------------------------------------------------------------------- 2007-02-19něco2007-02-20 (1 řádka) V PostgreSQL stále chyb́ı COLLATE. Podařilo se alespoň rozš́ı̌rit klauzuli ORDER a to Geinformatics FCE CTU 2007 93 PostgreSQL 8.3 v pozicováńı řádk̊u s hodnotou NULL (ORDER BY .. NULLS FIRST/LAST). Adekvátně tomu se rozš́ı̌rili parametry u btree index̊u. Refaktorizaćı kódu se doćılila podpora NULL v indexech. Starš́ı verze nedokázaly indexovat hodnotu NULL. postgres=# explain SELECT count(*) FROM fx WHERE a IS NULL; QUERY PLAN ------------------------------------------------------------------- Aggregate (cost=8.28..8.29 rows=1 width=0) -> Index Scan using bb on fx (cost=0.00..8.28 rows=1 width=0) Index Cond: (a IS NULL) (3 rows) Nové datové typy a rozš́ı̌reńı možnost́ı stávaj́ıćıch datových typ̊u Ve verzi 8.2 PostgreSQL podporuje několik nových datových typ̊u: XML zajǐst’uj́ıćı validitu obsahu, UUID (universal unique identifier) dle RFC 4122. Vlastńı generátor je v contribu uuid-ossp (je potřeba doinstalovat package uuid a uuid-devel). K dispozici je deset r̊uzných zp̊usob̊u generováńı jednoznačných univerzálńıch identifikátor̊u. Dále je tu možnost použ́ıvat vlastńı výčtové typy (zjevně inspirováno MySQL). Na rozd́ıl od MySQL v PostgreSQL je nutné před použit́ım vytvořit pro určitý seznam hodnot vlastńı typ. Jeho použit́ı je ovšem podstatně širš́ı než v MySQL. -- klasické řešenı́ výčtu CREATE TABLE foo(varianta char(2) CHECK (varianta IN (’a1’,’a2’,’a3’))); -- pouziti typu enum CREATE TYPE vycet_variant AS ENUM(’a1’,’a2’,’a3’,’a4’,’a5’); CREATE TABLE foo(varianta vycet_variant); -- enum lze pouzit i v poli SELECT ’{a1,a3}’::vycet_variant[] as pripustne_varianty; Rozsah hodnot źıskáme voláńım funkce enum range. Pokud funkci předáme parametr NULL, źıskáme úplný výčet hodnot. postgres=# SELECT enum_range(’a2’::va, ’a4’::vycet_variant); enum_range ------------ {a2,a3,a4} (1 row) postgres=# SELECT enum_range(null::vycet_variant); enum_range ------------------ {a1,a2,a3,a4,a5} (1 row) Kromě opravy několika chyb v PL/pgSQL (chyběla kontrola NOT NULL domén), došlo již k ńıže zmı́něnému rozš́ı̌reńı př́ıkazu RETURN o tabulkový výraz, a konečně lze i v PL/pgSQL použ́ıvat scrollable kurzory. Ty PostgreSQL podporuje deľśı dobu, z PL/pgSQL je však nebylo možné použ́ıvat. Kromě scrollable kurzor̊u lze v PL/pgSQL (ale i vně) použ́ıvat updatable kurzory podle ANSI SQL 92 (oproti ANSI SQL 2003 př́ısněǰśı omezeńı). U SRF funkćı můžeme upřesnit jejich náročnost a předpoklad počtu vrácených řádk̊u (atributy COST a ROWS). V předchoźıch verźıch se při hledáńı optimálńıho prováděćıho plánu předpokládalo, že SRF funkce vrát́ı vždy 1000 řádk̊u, což nebyla pokaždé být pravda (výsledkem byl neoptimálńı prováděćı plán). Vedleǰśım efektem implementace subsystému pro kešováńı prováděćıch plán̊u bylo odstraněńı problémů s neplatnými prováděćımi plány v PL/pgSQL. Tyto problémy se projevovaly hlavně při použit́ı dočasných tabulek, které se nesměly odstraňovat. Jinak docházelo, při použit́ı SQL Geinformatics FCE CTU 2007 94 PostgreSQL 8.3 př́ıkazu vázaného na zrušenou a opětovně vytvořenou tabulku, k chybě. Nyńı se cache čist́ı v závislosti na rušeńı databázových objekt̊u. Samozřejmě, že funkce volané v cyklu budou prováděny efektivně jen tehdy, pokud nebude docházet k regenerováńı prováděćıch plán̊u. V 8.3 můžeme pole vytvářet i ze složených typ̊u – v podstatě můžeme uložit tabulku jako jednu hodnotu). Stále však chyb́ı podpora domén (a vkládaný záznam je nutné explicitně typovat): postgres=# CREATE TYPE at AS (a integer, b integer); CREATE TYPE postgres=# CREATE TABLE foo(a at[]); CREATE TABLE postgres=# INSERT INTO foo VALUES(ARRAY[(10,20)::at]); INSERT 0 1 postgres=# INSERT INTO foo VALUES(ARRAY[(10,20)::at, (20,30)::at]); INSERT 0 1 postgres=# SELECT * FROM foo; a ----------------------- {"(10,20)"} {"(10,20)","(20,30)"} (2 rows) postgres=# SELECT a[1] FROM foo; a --------- (10,20) (10,20) (2 rows) postgres=# SELECT a[1].a FROM foo; a ---- 10 10 (2 rows) Optimalizace Ve verzi 8.3 došlo k celé řada změn a úprav, které by měly vést k rychleǰśımu zpracováńı SQL př́ıkaz̊u. Zrychlit by mělo nač́ıtáńı dat př́ıkazem COPY. U tohoto př́ıkazu neńı žádný d̊uvod, proč by mělo docházet k zápisu do write ahead logu (ten je základem procesu obnovy po pádu PostgreSQL) a tato verze dokáže u tohoto př́ıkazu obcházet zápis so WAL (COPY muśı být v transakci). Nově PostgreSQL efektivněji provád́ı dotazy s ORDER BY c LIMIT n, kdy znatelně zrychĺı výběr prvńıch n řádk̊u řazených podle sloupce c, pokud nad sloupcem c neńı index (nedocháźı k seřazeńı celé tabulky). Př́ıkaz EXPLAIN ANALYZE nyńı poskytuje daľśı informace o řazeńı (typ, spotřeba paměti): t=# explain analyze SELECT * FROM foo ORDER BY a LIMIT 12; QUERY PLAN ---------------------------------------------------------------------------------------------- Limit (cost=3685.48..3685.51 rows=12 width=4) (actual time=290.549..290.588 rows=12 loops=1) -> Sort (cost=3685.48..3935.48 rows=100000 width=4) (actual time=290.544..290.557 rows=12 loops=1) Sort Key: a Sort Method: top-N heapsort Memory: 17kB -> Seq Scan on foo (cost=0.00..1393.00 rows=100000 width=4) (actual time=0.036..153.526 rows=100000 loops=1) Total runtime: 290.658 ms (6 rows) t=# explain analyze SELECT * from foo order by a; Geinformatics FCE CTU 2007 95 PostgreSQL 8.3 QUERY PLAN --------------------------------------------------------------------------------------------- Sort (cost=10894.82..11144.82 rows=100000 width=4) (actual time=520.528..683.190 rows=100000 loops=1) Sort Key: a Sort Method: external merge Disk: 1552kB -> Seq Scan on foo (cost=0.00..1393.00 rows=100000 width=4) (actual time=0.022..159.028 rows=100000 loops=1) Total runtime: 800.065 ms (5 rows) V předchoźıch verźıch neexistovala hash funkce pro typ NUMERIC. Proto se pro spojováńı tabulek skrz sloupce typu NUMERIC nedala použ́ıt metoda HASHJOIN, která patř́ı k nej- rychleǰśım. Zrychlit by měla i operace LIKE, zvlášt’ když se použije v́ıce bajtové kódováńı – použil se jiný algoritmus na porovnáńı řetězc̊u. Nyńı se již neporovnávaj́ı znaky, ale bajty, což ušetř́ı jednu konverzi z UTF8 do UTF16. Na zkušebńı tabulce o sta tiśıćıch žlutých końıch sekvenčńı čteńı tabulky se zrychlilo z 169ms na 105ms. Pokud se zjist́ı, že docháźı k souběžnému sekvenčńımu čteńı jedné tabulky z v́ıce obslužných proces̊u, tak se systém pokuśı tyto procesy sesynchronizovat (pokud dojde k sekvenčńımu čteńı, tak se ve velké většině př́ıpad̊u čte celý datový soubor). Sekvenčńı čteńı všech proces̊u je přibližně stejně rychlé, a tak je šance, že všechny procesy budou cht́ıt v jednu chv́ıli stejnou datovou stránku, a je mnohem vyšš́ı pravděpodobnost, že ji najdou ve vyrovnávaćı paměti. Pokud nedocháźı k synchronizaci procesu, tak pravděpodobnost, že požadovaná stránka je ve vyrovnávaćı paměti je mnohem menš́ı, č́ımž se zvyšuje pravděpodobnost požadavku na fyzické čteńı datové stránky se souboru. Tato optimalizace má smysl při větš́ım počtu současně pracuj́ıćıch uživatel̊u, kdy je vyšš́ı pravděpodobnost, že dojde k synchronizaci, a také kdy je větš́ı tlak na vyrovnávaćı pamět’. Podpora asynchronńıho commitu je méně nebezpečnou obdobou nedoporučované konfigurace fsync=off. Při asynchronńım commitu je zaručena konzistence databáze, nicméně při havárii hroźı riziko ztráty několika posledńıch transakćı. Parametr synchronous commit je vázán na session, takže vývojář může na základě své úvahy zvolit méně bezpečný, nicméně rychleǰśı zp̊usob řešeńı transakćı. Testy ukazuj́ı, že má smysl uvažovat o tomto parametru v př́ıpadě málo zat́ıžené databáze, kdy nedocháźı ke sd́ıleńı zápisu do transakčńıho logu – typicky při administraci databáze, kdy ostatńı uživatelé nemaj́ı př́ıstup k databázi a s databáźı pracuje pouze DBA. 8.3 obsahuje sofistikovaněǰśı metodu pro vytvářeńı nových verźı označovanou jako HOT (Heap Only Tuples). Starš́ı verze při jakékoliv operaci UPDATE modifikovaly relevantńı indexy, a to i přesto, že nedošlo k modifikaci oindexovaných sloupc̊u. Tzv. horký UPDATE je podmı́něný dostatkem volného prostoru na datové stránce a změnou pouze neoindexovaných sloupc̊u. Po- kud tyto podmı́nky nejsou splněny, provede se klasický ”studený” UPDATE. HOT UPDATE je v̊uči klasické implementaci operace mnohem úsporněǰśı a tud́ıž i rychleǰśı. Nav́ıc tato nová metoda dokáže využ́ıt prostor na datové stránce obsazený nedostupnými verzemi (které byly vytvořeny také touto metodou) bez potřeby spuštěńı operace VACUUM. Geinformatics FCE CTU 2007 96 PostgreSQL 8.3 Spuštěńı operace VACUUM ve v́ıce procesech V 8.3 je automatické vacuováńı implementováno s podporou v́ıce proces̊u, tj. pokud trvá vacuum jedné databáze př́ılǐs dlouho, vytvoř́ı se nový pracovńı proces (worker), který zajǐst’uje vacuováńı daľśıch databáźı (smyslem neńı urychlit d́ıky paralelizaci operaci VACUUM, ale zajistit, že v daném časovém okně se provede spravedlivě VACUUM všech databáźı). Úkolem pracovńıho procesu je projet provozńı statistiky všech tabulek v databázi a vybrat tabulky určené k vacuováńı. Pracovńı proces je na úrovni databáze sekvenčńı, paralelizace je na úrovni clusteru. Nově vacuum také zajǐst’uje samočinné voláńı VACUUM FREEZE coby ochrany před přetečeńım rozsahu identifikátor̊u verźı řádk̊u. Rozš́ı̌reńı PL/pgSQL – RETURN QUERY, lokálńı systémové proměnné Předchoźı verze neumožňovaly vrátit množinu záznamů jako výsledek SRF funkce. Jediným řešeńım bylo voláńı př́ıkazu RETURN NEXT pro každý řádek výsledku dotazu. V podstatě totéž (ale na nižš́ı úrovni, tud́ıž efektivněji) provád́ı př́ıkaz RETURN QUERY. Jeho para- metrem je SQL dotaz, jehož výsledek se připoj́ı k výstupu. Podobně jako RETURN NEXT neukončuje prováděńı funkce. CREATE OR REPLACE FUNCTION dirty_series(m integer, n integer) RETURNS SETOF integer AS $$ BEGIN RETURN QUERY SELECT * FROM generate_series(1,m) g(i) WHERE i % n = 0; RETURN; END; $$ LANGUAGE plpgsq; Daľśı novou vlastnost́ı je možnost modifikovat systémové proměnné lokálně pro určitou funkci. Podobně se chová T-SQL nebo MySQL, kde se ukládá aktuálńı nastaveńı systémových promě- nných v čase registrace funkce. V PostgreSQL žádný podobný mechanismus nebyl. Tato vlastnost řeš́ı zabezpečeńı SECURITY DEFINER funkćı, kterým bylo možné podvrhnout útočńık̊uv kód změnou systémové proměnné search path. Zápis je zřejmý z následuj́ıćıho př́ıkladu: CREATE FUNCTION report_guc(text) RETURNS TEXT AS $$ SELECT current_setting($1) $$ LANGUAGE sql SET regex_flavor = basic; ALTER FUNCTION report_guc(text) RESET search_path SET regex_flavor = extended; Podpora režimu Warm Standby, prototyp replikace založené na transakčńım logu PostgreSQL 8.3 umožňuje nakonfigurovat a použ́ıvat dva PostgreSQL servery tak, že prvńı slouž́ı jako výkonný server a druhý jako záložńı, kdy změny v datech na prvńım serveru jsou na druhý server replikovány exportem transakčńıho logu. Tato konfigurace se použ́ıvá pouze v náročných aplikaćı, kde časté klasické zálohováńı z d̊uvodu objemu neńı možné a kde ztráta dat neńı akceptovatelná – kde zákazńık vyžaduje pr̊uběžné zálohováńı. Nejde o multi-master replikaci jako v př́ıpadě MySQL. Druhý systém je až do signálu nedostupný, tud́ıž t́ımto zp̊usobem replikace nelze rozložit zátěž serveru. Pro usnadněńı konfigurace verze 8.3 obsahuje př́ıkaz pg standby (ve stejnojmenném contrib adresáři), který zajist́ı udržeńı druhé instance PostgreSQL v režimu Warm Standby. Geinformatics FCE CTU 2007 97 PostgreSQL 8.3 Master (postgresql.conf): archive_command = ’cp %p ../archive/%f’ archive_timeout = 20 Warm Standby (recovery.conf) restore_command = ’pg_standby -l -d -k 255 -r 2 -s 2 -w 0 -t /tmp/stop /usr/local/pgsql/archive %f %p \ 2>> standby.log’ Po modifikaci konfiguračńıch soubor̊u stač́ı spustit oba servery. Záložńı server z̊ustane v re- covery režimu, kdy pg standby postupně podvrhuje segmenty transakčńıho logu (sleduje ex- portované segmenty) a nedovoĺı dokončit obnovu záložńı databáze. Teprve po signalizaci, pg standby (existenćı předem určeného souboru (v př́ıkladu /tmp/stop)) oznámı́ serveru, že se jednalo o posledńı segment transakčńıho logu a dovoĺı dokončeńı obnovy a t́ım i přepnut́ı do stavu, kdy záložńı server je schopen přij́ımat požadavky. Signálńı soubor muśı vygenerovat uživatel postgres, tak aby jej pg standby mohlo odstranit. Pokud tento soubor nelze odstra- nit, replikace zhavaruje. V praxi toto řešeńı neńı př́ılǐs použitelné, nebot’ pg standby nedokáže zachytit výjimku a tud́ıž ji ani nedokáže korektně obsloužit (aniž by nebyl nevratně přerušen proces replikace spojený se ztrátou dat na záložńım serveru). 4916 ? S 0:00 /usr/local/pgsql/bin/postmaster -D /usr/local/pgsql2/data 4918 ? Ss 0:00 postgres: startup process 5226 ? S 0:00 sh -c pg_standby -l -d -t /tmp/aaa /usr/local/pgsql/archive 000000010000000000000018 pg_xlog/RECOVERYXLOG 2>> standby.log 5227 ? S 0:00 pg_standby -l -d -t /tmp/aaa /usr/local/pgsql/archive 000000010000000000000018 pg_xlog/RECOVERYXLOG Záložńı cluster muśı být klonem zálohovaného clusteru. Muśı být vytvořen zkoṕırováńım adresáře databázového clusteru – nevytvář́ı se př́ıkazem initdb. Regulárńı výrazy Podpora reg. výraz̊u neńı v PostgreSQL novinkou. V 8.3 se objevily nové funkce regexp match- es a dvojice regexp split to array a regexp split to table. Pro řadu úloh nyńı nemuśıme pou- ž́ıvat plperl. V následuj́ıćım př́ıkladu je z XML dokumentu separován seznam identifikačńıch č́ısel, který je následně indexován a použit k vyhledáváńı. Ke stejnému účelu by bylo možné použ́ıt i funkce podporuj́ıćı XPath výrazy. Toto řešeńı je řádově rychleǰśı než intuitivńı (a velice pomalé) řešeńı s LIKE. objednava_v_xml LIKE ’%hledane_id%’ Pole NEW.objednavka id produktu je aktualizované v triggeru: NEW.objednavka_id_produktu := ARRAY(SELECT i[1] FROM regexp_matches(NEW.objednavka_v_xml,’(\\d+)’,’g’ r(i)); Funkčně srovnatelný predikát výše uvedenému LIKE je: objednavka_id_produktu @> ARRAY[hledane_id] Ostatńı změny Nezanedbatelného rozš́ı̌reńı se dočkalo prostřed́ı ecpg. Vylepšuje podporu prepared state- ments, nab́ıźı auto prepare mód, pozicované proměnné. Jedná o zásadńı změny – došlo ke změně verze z 4.4 na 6.0. Jednou z prvńıch backport̊u z EnterpriseDB je debugger a profiler PL/pgSQL. Nová verze pgAdminIII obsahuje grafické rozhrańı debuggeru, které je zpř́ıstupněno, pokud je v PostgreSQL nainstalován plugin s debuggerem (ke stažeńı na pg- foundry). Ve srovnáńı s moderńımi debuggery obsahuje PL/pgSQL pouze základńı funkce. Geinformatics FCE CTU 2007 98 PostgreSQL 8.3 pavel=# LOAD ’$libdir/plugins/plugin_profiler’; LOAD pavel=# SET plpgsql.profiler_tablename = ’profilerstats’; SET pavel=# SELECT line_number, sourcecode, time_total, exec_count, func_oid::regproc FROM profilerstats ORDER BY 1; line_number | sourcecode | time_total | exec_count | func_oid -------------+-----------------------+------------+------------+---------- 0 | | 0 | 0 | x 1 | begin | 0 | 0 | x 2 | for i in 1..4 loop | 0.000315 | 1 | x 3 | return next i; | 9.8e-05 | 4 | x 4 | end loop; | 0 | 0 | x 5 | return; | 3e-06 | 1 | x (6 rows) Index advisor Index advisor je plugin plánovače dotaz̊u. Jedná se o prototyp navržený Tomem Lanem za účelem demonstrace monitorovaćıho rozhrańı návrhu a optimalizace prováděćıch plán̊u. Pokud se aktivuje, tak optimalizátor bere v úvahu, kromě existuj́ıćıch index̊u, hypotetické indexy vytvořené nad každým sloupcem: regression=# load ’/home/tgl/pgsql/advisor’; LOAD regression=# explain select * from fooey order by unique2,unique1; QUERY PLAN ---------------------------------------------------------------------------------------- Sort (cost=809.39..834.39 rows=10000 width=8) Sort Key: unique2, unique1 -> Seq Scan on fooey (cost=0.00..145.00 rows=10000 width=8) Plan with hypothetical indexes: Index Scan using on fooey (cost=0.00..376.00 rows=10000 width=8) (6 rows) regression=# explain select * from fooey where unique2 in (1,2,3); QUERY PLAN ------------------------------------------------------------------------------------ Seq Scan on fooey (cost=0.00..182.50 rows=3 width=8) Filter: (unique2 = ANY (’{1,2,3}’::integer[])) Plan with hypothetical indexes: Bitmap Heap Scan on fooey (cost=12.78..22.49 rows=3 width=8) Recheck Cond: (unique2 = ANY (’{1,2,3}’::integer[])) -> Bitmap Index Scan on (cost=0.00..12.77 rows=3 width=0) Index Cond: (unique2 = ANY (’{1,2,3}’::integer[])) (8 rows) Vývoj v následuj́ıćıch letech Největš́ı slabinou PostgreSQL je chyběj́ıćı podpora replikaci. V této oblasti nikoliv neza- slouženě dominuj́ı komerčńı systémy. Dále PostgreSQL nemá dořešenou internacionalizaci, tzv. COLLATES, které nab́ıźı jak MySQL, tak Firebird. Konečně třet́ı oblast́ı, kterou je nyńı třeba intenzivně se zabývat je podpora OLAP databáźı. Nelze předpokládat, že by Postgre- SQL v brzké době podporoval OLAP databáze, nicméně existuj́ı určité indicie, že hlavńım tématem následuj́ıćı verze (8.4) bude podpora analytických a rekurzivńıch dotaz̊u. V deľśım Geinformatics FCE CTU 2007 99 PostgreSQL 8.3 časovém horizontu je možné očekávat zařazeńı podpory zpracováńı tzv. proudových dat, je- likož platforma PostgreSQL byla použita k vytvořeńı experimentálńıch prototyp̊u proudových databáźı a kromě toho, část týmu vývojář̊u se touto problematikou aktivně zabývá. Odkazy 1. Přehled vlastnost́ı jednotlivých verźı1 2. Přehled plánovaných rozš́ı̌reńı v př́ı̌st́ı verzi2 1 http://developer.postgresql.org/index.php/Feature Matrix 2 http://developer.postgresql.org/index.php/Todo:WishlistFor84 Geinformatics FCE CTU 2007 100 http://developer.postgresql.org/index.php/Feature_Matrix http://developer.postgresql.org/index.php/Todo:WishlistFor84