skolen ˇ ´ı postgresql efektivn eˇ · skolenˇ ´ı postgresql efektivn eˇ ... vyvoj z´...

58
ˇ Skolen´ ı PostgreSQL efektivnˇ e seobecn ´ ast + administrace - podklady Pavel Stˇ ehule http://www.postgres.cz 14. 7. 2015 Pavel Stˇ ehule (http://www.postgres.cz) ˇ Skolen´ ı PostgreSQL efektivnˇ e 14. 7. 2015 1 / 115 1 Podpora PostgreSQL na internetu 2 Instalace ve zkratce 3 Porovn ´ an´ ı o.s. SQL RDBMS Firebird, PostgreSQL, MySQL a SQLite 4 Minim ´ aln´ ı poˇ zadavky na datab´ azi, ACID krit´ eria 5 Charakteristick ´ e prvky PostgreSQL MGA, TOAST a WAL 6 Nutn ´ e zlo, pˇ ıkaz VACUUM 7 ´ Udrˇ zba datab ´ aze 8 Rozˇ siˇ ritelnost 9 akladn´ ı pˇ ıkazy pro spr ´ avu PostgreSQL 10 Export, import dat 11 alohov ´ an´ ı, obnova datab´ aze 12 Spr ´ ava uˇ zivatel ˚ u 13 Konfigurace datab´ aze 14 Monitorov ´ an´ ı datab ´ aze 15 Instalace dopl ˇ nk˚ u 16 Postup pˇ ri pˇ rechodu na novou verzi 17 Efektivn´ ı SQL 18 Pouˇ ıv´ an´ ı index˚ u 19 Optimalizace dotaz ˚ u 20 Sekvence 21 Vyhled ´ av´ an´ ı na z ´ aklad ˇ e podobnosti 22 Pole 23 Funkce generate series Pavel Stˇ ehule (http://www.postgres.cz) ˇ Skolen´ ı PostgreSQL efektivnˇ e 14. 7. 2015 2 / 115

Upload: truongcong

Post on 03-Mar-2019

223 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 1 115

1 Podpora PostgreSQL na internetu2 Instalace ve zkratce3 Porovnanı os SQL RDBMS Firebird PostgreSQL MySQL a SQLite4 Minimalnı pozadavky na databazi ACID kriteria5 Charakteristicke prvky PostgreSQL MGA TOAST a WAL6 Nutne zlo prıkaz VACUUM7 Udrzba databaze8 Rozsiritelnost9 Zakladnı prıkazy pro spravu PostgreSQL10 Export import dat11 Zalohovanı obnova databaze12 Sprava uzivatelu13 Konfigurace databaze14 Monitorovanı databaze15 Instalace doplnku16 Postup pri prechodu na novou verzi17 Efektivnı SQL18 Pouzıvanı indexu19 Optimalizace dotazu20 Sekvence21 Vyhledavanı na zaklade podobnosti22 Pole23 Funkce generate seriesPavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 2 115

Pavel Stehulepavelstehulegmailcom

vyvojar PostgreSQL od roku 1999 - vyvoj PLpgSQLlektor PostgreSQL a SQL od roku 2006instalace migrace databazı audit aplikacı postavenych nadPostgreSQLvyvoj zakaznickych modulu do PostgreSQL - vıce nahttpwwwpostgresczindexphpSluzbyinhouse skolenı PostgreSQLverejna skolenı SQL a PLpgSQLkonzultace ohledne problemu s vykonem (performance)PostgreSQLkomercnı podpora PostgreSQL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 3 115

Informace a podpora PostgreSQL na internetu

httpwikipostgresqlorghttpwwwpostgresqlorghttparchivespostgresqlorghttpwwwpostgresczhttpgroupsgooglecomgrouppostgresql-czhl=cshttppgxnorghttppgfoundryorgircircfreenodenetpostgresql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 4 115

Instalace ve zkratceInstalace z rpm archıvu

[pavellocalhost ~]$ su[rootlocalhost pavel] yum install postgresql[rootlocalhost pavel] yum install postgresql-server[rootlocalhost pavel] yum install php-pgsql[rootlocalhost pavel] yum install -i phpPgAdminnoarchrpm[rootlocalhost pavel] service postgresql initdb[rootlocalhost pavel] service postgresql start

postgres= SELECT name setting FROM pg_settingsWHERE name IN (data_directoryconfig_file)

name | setting----------------+---------------------------------------config_file | usrlocalpgsqldatapostgresqlconfdata_directory | usrlocalpgsqldata(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 5 115

Instalace ve zkratceRegistrace uzivatele pavel

[pavellocalhost ~]$ su[rootlocalhost pavel] su postgres[postgreslocalhost pavel] createuser pavelShall the new role be a superuser (yn) nShall the new role be allowed to create databases (yn) yShall the new role be allowed to create more new roles (yn) yCREATE ROLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 6 115

Instalace ve zkratcePostinstalacnı kontrola nastavenı locales

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt SHOW lc_collatelc_collate-------------cs_CZUTF-8(1 row)

postgres=gt SELECT upper(zluty kun)upper

-----------ZLUTY KUN(1 row)

PoznamkaPro Microsoft Windows je collate Czech Czech Republic

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 7 115

Porovnanı os SQL RDBMSSilna ctyrka

KandidatiFirebird vznikl v reakci na nejasnou licencnı politiku Borlandu v roce 2000na zaklade otevrenych kodu InterBase 60MySQL vznikl jako nahrada systemu mSQL v roce 1995 ve fyTcX(Svedsko) 2008 Sun 2009 OraclePostgreSQL vznikl doplnenım jazyka SQL do RDBMS Postgres(Berkeley95)SQLite je reakcı Richarda Hippa na velke RDBMS (USA 2000)

KriteriaPouzitelnost pro OLTP systemyPouzitelnost pro webPouzitelnost pro embedded systemyRestriktivnost licence

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 8 115

Porovnanı os SQL RDBMSPouzitelnost pro OLTP systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyspolehlivost (kriteria ACID)vysoka pruchodnost v silne konkurencnımprostredı dele trvajıcı transakcezajistenı referencnı domenove a entitnıintegritymaximalnı mozna podpora ANSI SQL(plna podpora prıkazu SELECT pohledyulozene procedury triggery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 9 115

Porovnanı os SQL RDBMSPouzitelnost pro web

Firebird25

PostgreSQL94

MySQL56

SQLite38

(MyISAM)

Pozadavkyvysoka pruchodnostvelmi rychle zpracovanı jednodussıchprıkazurychle vytvorenı spojenı mezi databazı aklientem extremne kratke transakcedatabaze musı zvladnout extremnıintenzitu prıkazudatabaze musı se musı vyrovnats intenzivnımi zmenami obsahu tabulek

PoznamkaOLTP aplikace byt s tenkym klientem zustavastale OLTP aplikacı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 10 115

Porovnanı os SQL RDBMSPouzitelnost pro Embedded systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyminimalnı systemove narokyminimalisticka instalace a sırenı (jedendatovy soubor jedna knihovna)spolehlivost schopnost automatickehozotavenı se z chybminimalnı pozadavky na provoznıadministraciminimalnı zavislosti

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 11 115

Porovnanı os SQL RDBMSRestriktivnost licence

Firebird25

PostgreSQL94

MySQL56

SQLite38

Restrikcepouzıvanı v nekomercnım prostredıpouzıvanı v komercnım prostredısırenı pro GPL aplikacesırenı pro ne GPL aplikacekomercnıho sırenı modifikovaneho kodu

Licence1 Public Domain (SQLite)2 BSD licence (PostgreSQL)3 licence IPL (Firebird)4 Dualnı GPL (pro os projekty a vlastnı i

komercnı pouzitı) a komercnı pro ostatnı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 12 115

Porovnanı os SQL RDBMSHodnocenı PostgreSQL

Firebird25

PostgreSQL94

MySQL56

SQLite38

DoporucenıDatabazovy system PostgreSQL je navrzenzejmena pro OLTP prostredı (podnikoveaplikace) Jako embedded databazi jejprakticky nasadit nelze V prostredı webu jevhodne nasadit PostgreSQL v kombinaci (pronetransakcnı data - napr www sessions logyatd) s memcached MySQL nebo SQLite

VarovanıNevhodny vyber DBMS muze vest kezvysenym nakladum na hw administraci nebok zbytecne komplikovanemu a nespolehlivemuresenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 13 115

Porovnanı os RDBMSHodnocenı PostgreSQL

Silne strankypodpora ANSI SQL 200xsofistikovany algoritmus zıskanı optimalnıho provadecıho planulicence BSDsnadne doplnovanı funkcionalitybohata nabıdka vestavenych datovych typurada kvalitnıch volne dostupnych doplnkusilny internı PL jazyk s vynikajıcı diagnostikou chybpodpora externıch PL jazyku

Slabe strankynutnost pravidelne spoustet prıkaz VACUUMdıky MGA v nekterych prıpadech limitujıcı rychlost zapisu a ctenınelze sdruzovat do clusterureplikacnı system umoznuje pouze master-slave replikaci

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 14 115

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 2: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Pavel Stehulepavelstehulegmailcom

vyvojar PostgreSQL od roku 1999 - vyvoj PLpgSQLlektor PostgreSQL a SQL od roku 2006instalace migrace databazı audit aplikacı postavenych nadPostgreSQLvyvoj zakaznickych modulu do PostgreSQL - vıce nahttpwwwpostgresczindexphpSluzbyinhouse skolenı PostgreSQLverejna skolenı SQL a PLpgSQLkonzultace ohledne problemu s vykonem (performance)PostgreSQLkomercnı podpora PostgreSQL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 3 115

Informace a podpora PostgreSQL na internetu

httpwikipostgresqlorghttpwwwpostgresqlorghttparchivespostgresqlorghttpwwwpostgresczhttpgroupsgooglecomgrouppostgresql-czhl=cshttppgxnorghttppgfoundryorgircircfreenodenetpostgresql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 4 115

Instalace ve zkratceInstalace z rpm archıvu

[pavellocalhost ~]$ su[rootlocalhost pavel] yum install postgresql[rootlocalhost pavel] yum install postgresql-server[rootlocalhost pavel] yum install php-pgsql[rootlocalhost pavel] yum install -i phpPgAdminnoarchrpm[rootlocalhost pavel] service postgresql initdb[rootlocalhost pavel] service postgresql start

postgres= SELECT name setting FROM pg_settingsWHERE name IN (data_directoryconfig_file)

name | setting----------------+---------------------------------------config_file | usrlocalpgsqldatapostgresqlconfdata_directory | usrlocalpgsqldata(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 5 115

Instalace ve zkratceRegistrace uzivatele pavel

[pavellocalhost ~]$ su[rootlocalhost pavel] su postgres[postgreslocalhost pavel] createuser pavelShall the new role be a superuser (yn) nShall the new role be allowed to create databases (yn) yShall the new role be allowed to create more new roles (yn) yCREATE ROLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 6 115

Instalace ve zkratcePostinstalacnı kontrola nastavenı locales

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt SHOW lc_collatelc_collate-------------cs_CZUTF-8(1 row)

postgres=gt SELECT upper(zluty kun)upper

-----------ZLUTY KUN(1 row)

PoznamkaPro Microsoft Windows je collate Czech Czech Republic

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 7 115

Porovnanı os SQL RDBMSSilna ctyrka

KandidatiFirebird vznikl v reakci na nejasnou licencnı politiku Borlandu v roce 2000na zaklade otevrenych kodu InterBase 60MySQL vznikl jako nahrada systemu mSQL v roce 1995 ve fyTcX(Svedsko) 2008 Sun 2009 OraclePostgreSQL vznikl doplnenım jazyka SQL do RDBMS Postgres(Berkeley95)SQLite je reakcı Richarda Hippa na velke RDBMS (USA 2000)

KriteriaPouzitelnost pro OLTP systemyPouzitelnost pro webPouzitelnost pro embedded systemyRestriktivnost licence

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 8 115

Porovnanı os SQL RDBMSPouzitelnost pro OLTP systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyspolehlivost (kriteria ACID)vysoka pruchodnost v silne konkurencnımprostredı dele trvajıcı transakcezajistenı referencnı domenove a entitnıintegritymaximalnı mozna podpora ANSI SQL(plna podpora prıkazu SELECT pohledyulozene procedury triggery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 9 115

Porovnanı os SQL RDBMSPouzitelnost pro web

Firebird25

PostgreSQL94

MySQL56

SQLite38

(MyISAM)

Pozadavkyvysoka pruchodnostvelmi rychle zpracovanı jednodussıchprıkazurychle vytvorenı spojenı mezi databazı aklientem extremne kratke transakcedatabaze musı zvladnout extremnıintenzitu prıkazudatabaze musı se musı vyrovnats intenzivnımi zmenami obsahu tabulek

PoznamkaOLTP aplikace byt s tenkym klientem zustavastale OLTP aplikacı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 10 115

Porovnanı os SQL RDBMSPouzitelnost pro Embedded systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyminimalnı systemove narokyminimalisticka instalace a sırenı (jedendatovy soubor jedna knihovna)spolehlivost schopnost automatickehozotavenı se z chybminimalnı pozadavky na provoznıadministraciminimalnı zavislosti

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 11 115

Porovnanı os SQL RDBMSRestriktivnost licence

Firebird25

PostgreSQL94

MySQL56

SQLite38

Restrikcepouzıvanı v nekomercnım prostredıpouzıvanı v komercnım prostredısırenı pro GPL aplikacesırenı pro ne GPL aplikacekomercnıho sırenı modifikovaneho kodu

Licence1 Public Domain (SQLite)2 BSD licence (PostgreSQL)3 licence IPL (Firebird)4 Dualnı GPL (pro os projekty a vlastnı i

komercnı pouzitı) a komercnı pro ostatnı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 12 115

Porovnanı os SQL RDBMSHodnocenı PostgreSQL

Firebird25

PostgreSQL94

MySQL56

SQLite38

DoporucenıDatabazovy system PostgreSQL je navrzenzejmena pro OLTP prostredı (podnikoveaplikace) Jako embedded databazi jejprakticky nasadit nelze V prostredı webu jevhodne nasadit PostgreSQL v kombinaci (pronetransakcnı data - napr www sessions logyatd) s memcached MySQL nebo SQLite

VarovanıNevhodny vyber DBMS muze vest kezvysenym nakladum na hw administraci nebok zbytecne komplikovanemu a nespolehlivemuresenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 13 115

Porovnanı os RDBMSHodnocenı PostgreSQL

Silne strankypodpora ANSI SQL 200xsofistikovany algoritmus zıskanı optimalnıho provadecıho planulicence BSDsnadne doplnovanı funkcionalitybohata nabıdka vestavenych datovych typurada kvalitnıch volne dostupnych doplnkusilny internı PL jazyk s vynikajıcı diagnostikou chybpodpora externıch PL jazyku

Slabe strankynutnost pravidelne spoustet prıkaz VACUUMdıky MGA v nekterych prıpadech limitujıcı rychlost zapisu a ctenınelze sdruzovat do clusterureplikacnı system umoznuje pouze master-slave replikaci

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 14 115

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 3: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Instalace ve zkratceInstalace z rpm archıvu

[pavellocalhost ~]$ su[rootlocalhost pavel] yum install postgresql[rootlocalhost pavel] yum install postgresql-server[rootlocalhost pavel] yum install php-pgsql[rootlocalhost pavel] yum install -i phpPgAdminnoarchrpm[rootlocalhost pavel] service postgresql initdb[rootlocalhost pavel] service postgresql start

postgres= SELECT name setting FROM pg_settingsWHERE name IN (data_directoryconfig_file)

name | setting----------------+---------------------------------------config_file | usrlocalpgsqldatapostgresqlconfdata_directory | usrlocalpgsqldata(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 5 115

Instalace ve zkratceRegistrace uzivatele pavel

[pavellocalhost ~]$ su[rootlocalhost pavel] su postgres[postgreslocalhost pavel] createuser pavelShall the new role be a superuser (yn) nShall the new role be allowed to create databases (yn) yShall the new role be allowed to create more new roles (yn) yCREATE ROLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 6 115

Instalace ve zkratcePostinstalacnı kontrola nastavenı locales

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt SHOW lc_collatelc_collate-------------cs_CZUTF-8(1 row)

postgres=gt SELECT upper(zluty kun)upper

-----------ZLUTY KUN(1 row)

PoznamkaPro Microsoft Windows je collate Czech Czech Republic

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 7 115

Porovnanı os SQL RDBMSSilna ctyrka

KandidatiFirebird vznikl v reakci na nejasnou licencnı politiku Borlandu v roce 2000na zaklade otevrenych kodu InterBase 60MySQL vznikl jako nahrada systemu mSQL v roce 1995 ve fyTcX(Svedsko) 2008 Sun 2009 OraclePostgreSQL vznikl doplnenım jazyka SQL do RDBMS Postgres(Berkeley95)SQLite je reakcı Richarda Hippa na velke RDBMS (USA 2000)

KriteriaPouzitelnost pro OLTP systemyPouzitelnost pro webPouzitelnost pro embedded systemyRestriktivnost licence

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 8 115

Porovnanı os SQL RDBMSPouzitelnost pro OLTP systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyspolehlivost (kriteria ACID)vysoka pruchodnost v silne konkurencnımprostredı dele trvajıcı transakcezajistenı referencnı domenove a entitnıintegritymaximalnı mozna podpora ANSI SQL(plna podpora prıkazu SELECT pohledyulozene procedury triggery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 9 115

Porovnanı os SQL RDBMSPouzitelnost pro web

Firebird25

PostgreSQL94

MySQL56

SQLite38

(MyISAM)

Pozadavkyvysoka pruchodnostvelmi rychle zpracovanı jednodussıchprıkazurychle vytvorenı spojenı mezi databazı aklientem extremne kratke transakcedatabaze musı zvladnout extremnıintenzitu prıkazudatabaze musı se musı vyrovnats intenzivnımi zmenami obsahu tabulek

PoznamkaOLTP aplikace byt s tenkym klientem zustavastale OLTP aplikacı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 10 115

Porovnanı os SQL RDBMSPouzitelnost pro Embedded systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyminimalnı systemove narokyminimalisticka instalace a sırenı (jedendatovy soubor jedna knihovna)spolehlivost schopnost automatickehozotavenı se z chybminimalnı pozadavky na provoznıadministraciminimalnı zavislosti

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 11 115

Porovnanı os SQL RDBMSRestriktivnost licence

Firebird25

PostgreSQL94

MySQL56

SQLite38

Restrikcepouzıvanı v nekomercnım prostredıpouzıvanı v komercnım prostredısırenı pro GPL aplikacesırenı pro ne GPL aplikacekomercnıho sırenı modifikovaneho kodu

Licence1 Public Domain (SQLite)2 BSD licence (PostgreSQL)3 licence IPL (Firebird)4 Dualnı GPL (pro os projekty a vlastnı i

komercnı pouzitı) a komercnı pro ostatnı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 12 115

Porovnanı os SQL RDBMSHodnocenı PostgreSQL

Firebird25

PostgreSQL94

MySQL56

SQLite38

DoporucenıDatabazovy system PostgreSQL je navrzenzejmena pro OLTP prostredı (podnikoveaplikace) Jako embedded databazi jejprakticky nasadit nelze V prostredı webu jevhodne nasadit PostgreSQL v kombinaci (pronetransakcnı data - napr www sessions logyatd) s memcached MySQL nebo SQLite

VarovanıNevhodny vyber DBMS muze vest kezvysenym nakladum na hw administraci nebok zbytecne komplikovanemu a nespolehlivemuresenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 13 115

Porovnanı os RDBMSHodnocenı PostgreSQL

Silne strankypodpora ANSI SQL 200xsofistikovany algoritmus zıskanı optimalnıho provadecıho planulicence BSDsnadne doplnovanı funkcionalitybohata nabıdka vestavenych datovych typurada kvalitnıch volne dostupnych doplnkusilny internı PL jazyk s vynikajıcı diagnostikou chybpodpora externıch PL jazyku

Slabe strankynutnost pravidelne spoustet prıkaz VACUUMdıky MGA v nekterych prıpadech limitujıcı rychlost zapisu a ctenınelze sdruzovat do clusterureplikacnı system umoznuje pouze master-slave replikaci

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 14 115

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 4: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Instalace ve zkratcePostinstalacnı kontrola nastavenı locales

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt SHOW lc_collatelc_collate-------------cs_CZUTF-8(1 row)

postgres=gt SELECT upper(zluty kun)upper

-----------ZLUTY KUN(1 row)

PoznamkaPro Microsoft Windows je collate Czech Czech Republic

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 7 115

Porovnanı os SQL RDBMSSilna ctyrka

KandidatiFirebird vznikl v reakci na nejasnou licencnı politiku Borlandu v roce 2000na zaklade otevrenych kodu InterBase 60MySQL vznikl jako nahrada systemu mSQL v roce 1995 ve fyTcX(Svedsko) 2008 Sun 2009 OraclePostgreSQL vznikl doplnenım jazyka SQL do RDBMS Postgres(Berkeley95)SQLite je reakcı Richarda Hippa na velke RDBMS (USA 2000)

KriteriaPouzitelnost pro OLTP systemyPouzitelnost pro webPouzitelnost pro embedded systemyRestriktivnost licence

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 8 115

Porovnanı os SQL RDBMSPouzitelnost pro OLTP systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyspolehlivost (kriteria ACID)vysoka pruchodnost v silne konkurencnımprostredı dele trvajıcı transakcezajistenı referencnı domenove a entitnıintegritymaximalnı mozna podpora ANSI SQL(plna podpora prıkazu SELECT pohledyulozene procedury triggery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 9 115

Porovnanı os SQL RDBMSPouzitelnost pro web

Firebird25

PostgreSQL94

MySQL56

SQLite38

(MyISAM)

Pozadavkyvysoka pruchodnostvelmi rychle zpracovanı jednodussıchprıkazurychle vytvorenı spojenı mezi databazı aklientem extremne kratke transakcedatabaze musı zvladnout extremnıintenzitu prıkazudatabaze musı se musı vyrovnats intenzivnımi zmenami obsahu tabulek

PoznamkaOLTP aplikace byt s tenkym klientem zustavastale OLTP aplikacı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 10 115

Porovnanı os SQL RDBMSPouzitelnost pro Embedded systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyminimalnı systemove narokyminimalisticka instalace a sırenı (jedendatovy soubor jedna knihovna)spolehlivost schopnost automatickehozotavenı se z chybminimalnı pozadavky na provoznıadministraciminimalnı zavislosti

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 11 115

Porovnanı os SQL RDBMSRestriktivnost licence

Firebird25

PostgreSQL94

MySQL56

SQLite38

Restrikcepouzıvanı v nekomercnım prostredıpouzıvanı v komercnım prostredısırenı pro GPL aplikacesırenı pro ne GPL aplikacekomercnıho sırenı modifikovaneho kodu

Licence1 Public Domain (SQLite)2 BSD licence (PostgreSQL)3 licence IPL (Firebird)4 Dualnı GPL (pro os projekty a vlastnı i

komercnı pouzitı) a komercnı pro ostatnı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 12 115

Porovnanı os SQL RDBMSHodnocenı PostgreSQL

Firebird25

PostgreSQL94

MySQL56

SQLite38

DoporucenıDatabazovy system PostgreSQL je navrzenzejmena pro OLTP prostredı (podnikoveaplikace) Jako embedded databazi jejprakticky nasadit nelze V prostredı webu jevhodne nasadit PostgreSQL v kombinaci (pronetransakcnı data - napr www sessions logyatd) s memcached MySQL nebo SQLite

VarovanıNevhodny vyber DBMS muze vest kezvysenym nakladum na hw administraci nebok zbytecne komplikovanemu a nespolehlivemuresenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 13 115

Porovnanı os RDBMSHodnocenı PostgreSQL

Silne strankypodpora ANSI SQL 200xsofistikovany algoritmus zıskanı optimalnıho provadecıho planulicence BSDsnadne doplnovanı funkcionalitybohata nabıdka vestavenych datovych typurada kvalitnıch volne dostupnych doplnkusilny internı PL jazyk s vynikajıcı diagnostikou chybpodpora externıch PL jazyku

Slabe strankynutnost pravidelne spoustet prıkaz VACUUMdıky MGA v nekterych prıpadech limitujıcı rychlost zapisu a ctenınelze sdruzovat do clusterureplikacnı system umoznuje pouze master-slave replikaci

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 14 115

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 5: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Porovnanı os SQL RDBMSPouzitelnost pro OLTP systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyspolehlivost (kriteria ACID)vysoka pruchodnost v silne konkurencnımprostredı dele trvajıcı transakcezajistenı referencnı domenove a entitnıintegritymaximalnı mozna podpora ANSI SQL(plna podpora prıkazu SELECT pohledyulozene procedury triggery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 9 115

Porovnanı os SQL RDBMSPouzitelnost pro web

Firebird25

PostgreSQL94

MySQL56

SQLite38

(MyISAM)

Pozadavkyvysoka pruchodnostvelmi rychle zpracovanı jednodussıchprıkazurychle vytvorenı spojenı mezi databazı aklientem extremne kratke transakcedatabaze musı zvladnout extremnıintenzitu prıkazudatabaze musı se musı vyrovnats intenzivnımi zmenami obsahu tabulek

PoznamkaOLTP aplikace byt s tenkym klientem zustavastale OLTP aplikacı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 10 115

Porovnanı os SQL RDBMSPouzitelnost pro Embedded systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyminimalnı systemove narokyminimalisticka instalace a sırenı (jedendatovy soubor jedna knihovna)spolehlivost schopnost automatickehozotavenı se z chybminimalnı pozadavky na provoznıadministraciminimalnı zavislosti

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 11 115

Porovnanı os SQL RDBMSRestriktivnost licence

Firebird25

PostgreSQL94

MySQL56

SQLite38

Restrikcepouzıvanı v nekomercnım prostredıpouzıvanı v komercnım prostredısırenı pro GPL aplikacesırenı pro ne GPL aplikacekomercnıho sırenı modifikovaneho kodu

Licence1 Public Domain (SQLite)2 BSD licence (PostgreSQL)3 licence IPL (Firebird)4 Dualnı GPL (pro os projekty a vlastnı i

komercnı pouzitı) a komercnı pro ostatnı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 12 115

Porovnanı os SQL RDBMSHodnocenı PostgreSQL

Firebird25

PostgreSQL94

MySQL56

SQLite38

DoporucenıDatabazovy system PostgreSQL je navrzenzejmena pro OLTP prostredı (podnikoveaplikace) Jako embedded databazi jejprakticky nasadit nelze V prostredı webu jevhodne nasadit PostgreSQL v kombinaci (pronetransakcnı data - napr www sessions logyatd) s memcached MySQL nebo SQLite

VarovanıNevhodny vyber DBMS muze vest kezvysenym nakladum na hw administraci nebok zbytecne komplikovanemu a nespolehlivemuresenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 13 115

Porovnanı os RDBMSHodnocenı PostgreSQL

Silne strankypodpora ANSI SQL 200xsofistikovany algoritmus zıskanı optimalnıho provadecıho planulicence BSDsnadne doplnovanı funkcionalitybohata nabıdka vestavenych datovych typurada kvalitnıch volne dostupnych doplnkusilny internı PL jazyk s vynikajıcı diagnostikou chybpodpora externıch PL jazyku

Slabe strankynutnost pravidelne spoustet prıkaz VACUUMdıky MGA v nekterych prıpadech limitujıcı rychlost zapisu a ctenınelze sdruzovat do clusterureplikacnı system umoznuje pouze master-slave replikaci

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 14 115

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 6: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Porovnanı os SQL RDBMSPouzitelnost pro Embedded systemy

Firebird25

PostgreSQL94

MySQL56

SQLite38

(InnoDB)

Pozadavkyminimalnı systemove narokyminimalisticka instalace a sırenı (jedendatovy soubor jedna knihovna)spolehlivost schopnost automatickehozotavenı se z chybminimalnı pozadavky na provoznıadministraciminimalnı zavislosti

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 11 115

Porovnanı os SQL RDBMSRestriktivnost licence

Firebird25

PostgreSQL94

MySQL56

SQLite38

Restrikcepouzıvanı v nekomercnım prostredıpouzıvanı v komercnım prostredısırenı pro GPL aplikacesırenı pro ne GPL aplikacekomercnıho sırenı modifikovaneho kodu

Licence1 Public Domain (SQLite)2 BSD licence (PostgreSQL)3 licence IPL (Firebird)4 Dualnı GPL (pro os projekty a vlastnı i

komercnı pouzitı) a komercnı pro ostatnı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 12 115

Porovnanı os SQL RDBMSHodnocenı PostgreSQL

Firebird25

PostgreSQL94

MySQL56

SQLite38

DoporucenıDatabazovy system PostgreSQL je navrzenzejmena pro OLTP prostredı (podnikoveaplikace) Jako embedded databazi jejprakticky nasadit nelze V prostredı webu jevhodne nasadit PostgreSQL v kombinaci (pronetransakcnı data - napr www sessions logyatd) s memcached MySQL nebo SQLite

VarovanıNevhodny vyber DBMS muze vest kezvysenym nakladum na hw administraci nebok zbytecne komplikovanemu a nespolehlivemuresenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 13 115

Porovnanı os RDBMSHodnocenı PostgreSQL

Silne strankypodpora ANSI SQL 200xsofistikovany algoritmus zıskanı optimalnıho provadecıho planulicence BSDsnadne doplnovanı funkcionalitybohata nabıdka vestavenych datovych typurada kvalitnıch volne dostupnych doplnkusilny internı PL jazyk s vynikajıcı diagnostikou chybpodpora externıch PL jazyku

Slabe strankynutnost pravidelne spoustet prıkaz VACUUMdıky MGA v nekterych prıpadech limitujıcı rychlost zapisu a ctenınelze sdruzovat do clusterureplikacnı system umoznuje pouze master-slave replikaci

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 14 115

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 7: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Porovnanı os SQL RDBMSHodnocenı PostgreSQL

Firebird25

PostgreSQL94

MySQL56

SQLite38

DoporucenıDatabazovy system PostgreSQL je navrzenzejmena pro OLTP prostredı (podnikoveaplikace) Jako embedded databazi jejprakticky nasadit nelze V prostredı webu jevhodne nasadit PostgreSQL v kombinaci (pronetransakcnı data - napr www sessions logyatd) s memcached MySQL nebo SQLite

VarovanıNevhodny vyber DBMS muze vest kezvysenym nakladum na hw administraci nebok zbytecne komplikovanemu a nespolehlivemuresenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 13 115

Porovnanı os RDBMSHodnocenı PostgreSQL

Silne strankypodpora ANSI SQL 200xsofistikovany algoritmus zıskanı optimalnıho provadecıho planulicence BSDsnadne doplnovanı funkcionalitybohata nabıdka vestavenych datovych typurada kvalitnıch volne dostupnych doplnkusilny internı PL jazyk s vynikajıcı diagnostikou chybpodpora externıch PL jazyku

Slabe strankynutnost pravidelne spoustet prıkaz VACUUMdıky MGA v nekterych prıpadech limitujıcı rychlost zapisu a ctenınelze sdruzovat do clusterureplikacnı system umoznuje pouze master-slave replikaci

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 14 115

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 8: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

PostgreSQL v kostceArchitektura

Popisklasicky klient-server systemkomunikace prostrednictvımUDF TCPIP nebo SSLprotokoluvıceprocesovy system noveprocesy vznikajı prı vytvorenıspojenıvzdy jedno spojenı jedenprocesexistuje moznost poolinguspojenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 15 115

PostgreSQL v kostceDatabazovy cluster

Cluster obsahujedatove souborypracovnı souborykonfiguracnı souboryseznam uzivatelu a zvolene LOCALES

Mapovanı na sys zdrojeclusterrarr adresardatabazerarr adresartabulkararr soubor

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 16 115

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 9: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

PostgreSQL v kostceLogicke clenenıfyzicke clenenı databaze

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 17 115

Inicializace clusteruSprava datoveho adresare

InicializaceSlovo cluster ma v PostgreSQL vyznam prostoru pro vsechny databaze kekterym lze pristupovat urcenou IP adresou a portem Vsechny databaze vclusteru sdılı konfiguaraci a uzivatele Na jednom pocıtaci lze provozovat vıceclusteru stejnych nebo ruznych verzı PostgreSQL

initdb [OPTION] [DATADIR]-E --encoding=ENCODING urcı kodovanı--locale=LOCALE urcı locales

Poznamkyv clusteru nic nemazat (pg resetxlog)z clusteru nekopırovat datove soubory (neprenosne)lze kopırovat cely adresar clusteru (zastavene PostgreSQL)lze kopırovat cely adresar clusteru (aktivnı export write ahead logu)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 18 115

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 10: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Udrzba databazeSprava datoveho adresare

Umıstenı datoveho adresarelisı se dle zvyklostı konkretnıch distribucı

default usrlocalpgsqldata vytvarı se rucneRed Hat varlibpgsqldata vytvarı se automaticky pri prvnım startu

Kontrola korektnıho chovanı LOCALEOkamzite po instalaci overte zda je korektne podporovano narodnı prostredıNejlepe SELECT upper(rsquoprılis zlutoucky kunrsquo) Vybrane locale clusteruse musı shodovat s kodovanım databaze napr pro UTF8 musıme pouzıvatlocale cs CZUTF8

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 19 115

PostgreSQL v kostceZpracovanı dotazu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 20 115

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 11: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Pozadavky na transakcnı databazove systemytzv ACID kriteria

Transakcnı systemZa transakcnı system povazujeme kazdy system ktery splnuje kriteria ACID

Kriteria ACIDAtomicnost V ramci transakce se provedou vzdy vsechny prıkazy nebo zadnyKonzistence Transakce prevadı data vzdy z jednoho konzistentnıho stavu do

druheho Uvnitr transakce tato podmınka neplatıIzolace Transakce se navzajem neovlivnujı

Trvanlivost Pokud je transakce potvrzena pak jsou zmeny trvale

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 21 115

Multigeneracnı architekturaMulti Value Concurency Control

IdeaMısto prepisu zaznamu zaznamy kopırujeme Viditelne jsou pouze ty verzezaznamu ktere se vazı na potvrzene transakce nebo nejnovejsı verzevytvorene aktualnı transakcı

MotivaceDuvodem implementace jsou ACID pozadavky konzistence a izolace Systemmusı dokazat odstranit zmeny zpusobene nedokoncenou nebo prerusenoutransakcı System musı zajistit izolaci transakcı tj z transakce nikdy nejsouviditelne zmeny jinych nepotvrzenych transakcı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 22 115

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 12: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Multigeneracnı architekturaMulti Value Concurency Control

VyhodyMinimalizace prıpadu kdy je nutne pouzıt zamek Vzdy je k dispozicipuvodnı varianta zaznamu tudız nepotvrzene transakce neblokujı ctenıVysoka prostupnost v konkurencnım prostredıNarocnost operacı ROLLBACK a COMMIT nezavisı na objemuodvolavanych nebo potvrzovanych dat Stacı pouze potvrzenı nebonepotvrzenı transakce v seznamu provedenych transakcı Nikdynedochazı k presunu dat

NevyhodyNutnost odstranovat nedostupne zaznamy Databaze bobtnaVzhledem k slozitejsımu zpusobu ukladanı dat nekolikanasobne azradove pomalejsı ctenı a zapis do databazeChybı podpora tzv spinaveho ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 23 115

Datove typy bez limitu - TOASTThe Oversized Attribute Storage Technique

MotivaceOdstranenı limitu 8KB na max velikost zaznamu (velikost datove stranky)Usporne ukladanı textovych dat

ResenıU polozek delsıch 32 byte se zjistuje efektivita komprimace Pokud je ucinnostvetsı nez 25 data se ukladajı do tabulky TOAST komprimovane Podle typuuloziste (EXTERNAL EXTENDED) se ukladana data rozdelı do posloupnosti2KB bloku a ulozı do tabulky TOAST Vse je pro uzivatele transparentnı

EfektyMaximalnı velikost textovych typu je 1GB (prakticke je 6-10MB)Usporne ukladanı textovych dat (napr 50 u textu v HTML)Narocnejsı (byt transparentnı) prıstup k polozkam delsıch 2KB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 24 115

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 13: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

PostgreSQL v kostceVarianty ulozenı dat - plain main extended external

Strategie TOASTV prıpade ze radek presahne urcitou velikost (typicky 2KB) dochazı kpresouvanı nejdelsıch hodnot do pridruzene tabulky TOAST a to tak dlouhodokud se nedosahne pozadovane velikosti (2KB)

VariantyPlain - blokuje komprimaci blokuje ukladanı mimo tabulku (max

velikost 8KB) vychozı pro typy s fixnı delkouMain - data jsou komprimovana a pokud je to mozne tak ulozena

lokalneExtended - data jsou komprimovana a ukladana mimo tabulku (out-of-line)

(pokud je to nutne) vychozı varianta pro tzv varlena typyExternal - data jsou ukladana mimo tabulku - nekomprimovana (rychlejsı

operace substring - spec optimalizace)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 25 115

Spolehlivost a vykon - WALWrite ahead logging

MotivaceJe resenım ACID pozadavku na trvanlivost Kazda zmena datovych souborumusı byt jistena predchozım zapisem do transakcnıho logu

EfektyV prıpade vypadku lze databazi obnovit z transakcnıho logu tj jezajistena konzistence datovych souboru a indexuPri potvrzenı transakce je nutne provest operaci fsync pouze natransakcnım logu (nikoliv nad datovymi soubory) Vysledkem je zasadnızvysenı vykonu Sdılenım transakcnıho logu dochazı k dalsı redukcifsyncuTransakcnı log lze exportovat na bezpecne medium tj on-line zalohovanıa PITR (Point In Time Recovery)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 26 115

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 14: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Nutne zlo prıkaz VACUUM

prıkaz ANALYZEAktualizuje datove statistiky pouzite optimalizatorem dotazu (velikost tabulekhistogramy hodnot pro jednotlive sloupce)

prıkaz VACUUMOdstranuje nedostupne (mrtve) verze zaznamu z datovych souboru Uvolnujeprostor jimi obsazeny a zaroven zrychluje prıstup k dostupnym zaznamum (prictenı se nepreskakujı mrtve zaznamy)

VarovanıV prıpade ze podıl mrtvych variant zaznamu dosahne 30 dochazık znatelnemu zpomalenı vsech operacı nad tabulkou Pokud nedojdek provedenı prıkazu VACUUM muze byt databaze po urcitem case praktickynefunkcnı pricemz generuje znacnou zatez serveru Obranou je pravidelnespoustenı prıkazu VACUUM nebo aktivace procesu pg autovacuum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 27 115

Nutne zlo prıkaz VACUUMVarianty prıkazu VACUUM

Variace prıkazuVACUUM ktere nevyzaduje zadny zamek tabulkyVACUUM ANALYZE zaroven provede aktualizaci statistikVACUUM FULL provede reorganizaci zaznamu na disku (zaplnenımmezer) Vyzaduje exkluzivnı zamek nad tabulkouVACUUM FREEZE provede rdquozmrazenırdquo vsech aktualnıch zivych zaznamua resetuje cıtac transakcı

Zmrazenı zaznamuKazdy zaznam obsahuje 4byte identifikator transakce ktera jej vytvorila Privycerpanı (pretecenı) 4byte prostoru hrozı kolaps MGA mechanismurdquoZmrazenırdquo zaznamu znamena ze jeho transaction ID je nastaveno napreddefinovanou hodnotu FroozenXID

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 28 115

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 15: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Nutne zlo prıkaz VACUUMResenı

Periodicke spoustenı prıkazu VACUUMPro

presne nacasovanı spustenı prıkazuProti

obtızne se odhaduje optimalnı frekvence spoustenı prıkazuza aktivaci zodpovıda externı sluzba coz muze zpusobovat provoznı aadministrativnı problemy

Proces pg autovacuumPro

relativne presne nacasovanı spoustenı prıkazuProti

pokud se spustı rdquonevhodnerdquo zpusobı snızenı vykonu systemu (rezie)vyzaduje zapnutı provoznıch statistik (20 rezie)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 29 115

Udrzba databazeOpakujıcı se cinnosti

Pravidelne1x denne VACUUM ANALYZE (cron autovacuum)1x mesıcne REINDEX databaze nebo alespon nejcasteji modifikovanychtabulek

Nepravidelnepokud dochazı vyhrazeny prostor na disku pro data VACUUM FULLpokud hrozı pretecenı cıtace transakcı (varovanı v logu) VACUUM FREEZE(1x za nekolik let)analyza pomalych dotazu (limit 200ms) a jejich eliminace pridanım novychindexucistenı datoveho schema (nutno zalohovat a dokumentovat)

odstranenı nepouzıvanych tabulek (pg stat all tables)odstranenı nepouzıvanych indexu (pg stat all indexes)

Kazdy index zabıra prostor na disku a zpomaluje operace INSERT UPDATEDELETE Proto indexy vytvarıme pouze tehdy kdyz majı nejaky efekt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 30 115

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 16: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Udrzba databazeZastavenı spustenı PostgreSQL

Start Reload Restart serveruetcinitdpostgres (start|reload|restart|stop|status)pg ctl lze specifikovat rezimy ukoncenı

smart ceka az se odhlası vsichni klientifast neceka na odhlasenı klientu provede uplny proces ukoncenıimmediate skoncı okamzite s dusledkem obnovy po nekorektnım ukoncenıpri prıstım startu

Preferujeme co nejsetrnejsı moznou metodu V prıpade podivneho chovanıjednoho klientskeho procesu lze zaslat signal sigint obsluznemu procesuklienta

Ukoncenı klienta z prostredı SQL1 zıskanı pid problemoveho klienta

select procpid usename current_query from pg_stat_activityprocpid | usename | current_query

10144 | root | select fce()2 odstranenı procesu select pg cancel backend(10144)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 31 115

Udrzba databazeZastavenı spustenı PostgreSQL

Obnova po havariiPokud server nebyl ukoncen korektne je mozne ze v pameti zustanouservisnı procesy PostgreSQL Ty je nutne pred opetovnym spustenım serveruukoncit Vyjmecne je nutne vycistit sdılenou pamet prıkazem ipcclean Takeje nutne explicitne odstranit soubor dbclusterpostmasterpid Zanormalnıch okolnostı se spustı automaticky proces obnovy databaze nazaklade udaju ulozenych ve write ahead logu

DoporucenıJe celkem na mıste overit integritu databaze dumpem databaze V prıpadeproblemu

reindexace databaze vcetne systemovych tabulekobnova ze zalohyidentifikace poskozenych radku a jejich odstranenı Prıznakem poskozenedatabaze je pad serveru pri sekvencnım ctenı

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 32 115

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 17: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Rozsiritelnost PostgreSQLVlastnı funkce

Navrh vlastnıch funkcıC PLpgSQL PLSQL PLPerl PLPython PLJava PLPhp PLRPodpora OUT parametruPodpora Set Returning Functions (vysledkem je tabulka)Podpora osetrenı chybPodpora polymorfismu

CREATE OR REPLACE FUNCTIONplvstrswap(str text replace text start int length int)RETURNS textAS $libdirorafuncplvstr_swapLANGUAGE c STABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 33 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka SQL funkce

Funkce signFunkce mysign vracı hodnotu -1 pro zaporny argument hodnotu 0 pro nulu ahodnotu 1 pro kladne nenulove cıslo

CREATE OR REPLACE FUNCTION mysign(a numeric)RETURNS numeric AS $$SELECT CASE WHEN $1 lt 0 THEN -1numeric

WHEN $1 gt 0 THEN 1numericELSE 0numeric END

$$ LANGUAGE sql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 34 115

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 18: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Rozsiritelnost PostgreSQLVlastnı funkce ukazka funkce v Perlu

Funkce rsplitFunkce rsplit vracı vracı pole retezcu identifikovanych regularnım vyrazemNapr vysledkem rsplit(rsquo123456 22rsquorsquo([0-9]+)rsquo je pole 12345622

CREATE OR REPLACE FUNCTION rsplit(text text)RETURNS text[]AS $$

my result = ($$_[0] =~ $_[1]g)return result

$$ LANGUAGE plperl IMMUTABLE STRICT

-- totez v 83SELECT ARRAY(SELECT re[1]

FROM regexp_matches(123456 789ed+g) re)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 35 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro typ interval

Operace delenı pro typ intervalVysledkem rsquo1 hoursrsquo rsquo10 minutes je cıselna hodnota 6

CREATE FUNCTION div(interval interval)RETURNS double precision AS $$SELECT EXTRACT(epoch FROM $1) EXTRACT(epoch from $2)

$$ LANGUAGE sql

CREATE OPERATOR (PROCEDURE = divLEFTARG = interval rightarg = interval)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 36 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 19: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Rozsiritelnost PostgreSQLVlastnı operator ukazka operatoru div pro modifikovany operator nerovnosti

Operator nerovno inertnı hodnote NULLChceme aby platilo i pro NULL ze NULL ltgt konstanta

CREATE OR REPLACE FUNCTION cmp_ne_spec(anyelement anyelement)RETURNS boolean AS $$SELECT $1 IS NULL OR $2 IS NULL OR $1 ltgt $2

$$ LANGUAGE sql

CREATE OPERATOR ltltgtgt (PROCEDURE=cmp_ne_specLEFTARG=anyelementRIGHTARG=anyelemeny)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 37 115

Rozsiritelnost PostgreSQLVlastnı operator ukazka vlastnı automaticke konverze z int na timestamp

Automaticka konverze integer na timestampPrevadı unix cas (pocet sec od 111970) na PostgreSQL timestamp Naprvysledkem 0timestamp je 111970 000000

CREATE FUNCTION to_timestamp(integer)RETURNS timestamp with time zone AS $$SELECT to_timestamp($1float8)

$$ LANGUAGE sql

CREATE CAST (integer AS timestamp with time zone)WITH FUNCTION to_timestamp(integer)AS IMPLICIT

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 38 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 20: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Zakladnı prıkazy pro spravu PostgreSQLSeznam prıkazu

Pro prıstup a pouzıvanı databazecreatedb zalozı novou databazi

dropdb odstranı existujıcı databazicreatelang zprıstupnı PL (prg jazyk ulozenych procedur) urcite databazi

psql sql konzole umoznujıcı zadavanı SQL prıkazu

Pro administracivacuumdb spoustı vacuum databazereindexdb znovu vytvorı indexy v databazi

createuser prida uzivatele do databazoveho clusterudropuser odstranı uzivatele z databazoveho clusteru

oid2name zobrazuje cıselny identifikator jako textpg dump vytvorı dump databaze

pg dumpall vytvorı dump celeho databazoveho clusteruinitdb inicializuje databazovy cluster

pgbench TPC-B test vykonu (hrube overenı instalace)pg restore obnovı databazi ze zalohy

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 39 115

Zakladnı prıkazy pro spravu PostgreSQLSeznam metaprıkazu psql

Metaprıkazyh napoveda k SQL prıkazum napoveda k metaprıkazumq ukoncenı konzoler vycistenı vyrovnavacı pameti textu dotazui provedenı SQL prıkazu ze souborul seznam databazıd popis objektudt seznam tabulekdf seznam funkcıdn seznam schematx prepınanı mezi sloupcovym a radkovym zobrazenım

timing prepına zobrazenı doby provadenı dotazutab autocomplete

ctrl+r vyhledavanı v historii

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 40 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 21: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

[pavellocalhost ~]$ psql postgrespsql (903)Type help for help

postgres=gt h create triggerCommand CREATE TRIGGERDescription define a new triggerSyntaxCREATE TRIGGER name BEFORE | AFTER event [ OR ]

ON table [ FOR [ EACH ] ROW | STATEMENT ]EXECUTE PROCEDURE funcname ( arguments )

postgres=gt d fooTable ``publicfoo

Column | Type | Modifiers--------+-------------------+-----------i | integer |a | character varying |

postgres=gt

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 41 115

Zakladnı prıkazy pro spravu PostgreSQLUkazka psql konzole

postgres=gt select current_timetimetz

--------------------134508833422+02(1 row)

postgres=gt CREATE OR REPLACE FUNCTION hello(varchar)postgres-gt RETURNS varcharpostgres-gt AS $$postgres$$gt BEGINpostgres$gt RETURN Hello || $1postgres$gt ENDpostgres$gt $$ LANGUAGE plpgsql stableCREATE FUNCTIONpostgres=gtpostgres=gt select hello(world)

hello-------------Hello world(1 row)

postgres=gt q[pavellocalhost ~]$$

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 42 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 22: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı metaprıkazu

postgres= dtList of relations

Schema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavelpublic | comp | table | pavelpublic | dual | table | pavel

postgres= d fooTable publicfoo

Column | Type | Modifiers--------+---------+-----------a | integer |

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 43 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - dohledanı zdroju

[pavelokbob-bb ~]$ psql -E postgres

postgres= dt QUERY SELECT nnspname as lsquolsquoSchemarsquorsquo

crelname as lsquolsquoNamersquorsquoCASE crelkind WHEN rsquorrsquo THEN rsquotablersquo WHEN rsquovrsquo THEN rsquoviewrsquo

WHEN rsquoirsquo THEN rsquoindexrsquo WHEN rsquoSrsquo THEN rsquosequencersquoWHEN rsquosrsquo THEN rsquospecialrsquo END as lsquolsquoTypersquorsquo

rrolname as lsquolsquoOwnerrsquorsquoFROM pg_catalogpg_class c

JOIN pg_catalogpg_roles r ON roid = crelownerLEFT JOIN pg_catalogpg_namespace n ON noid = crelnamespace

WHERE crelkind IN (rsquorrsquorsquorsquo)AND nnspname NOT IN (rsquopg_catalogrsquo rsquopg_toastrsquo)

AND pg_catalogpg_table_is_visible(coid)ORDER BY 12

List of relationsSchema | Name | Type | Owner--------+--------------+-------+-------public | accounts | table | pavelpublic | branches | table | pavel

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 44 115

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 23: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Zakladnı prıkazy pro spravu PostgreSQLSystemovy katalog - pouzitı informacnıch schemat

postgres= select table_name table_schemafrom information_schematableswhere table_schema = rsquopublicrsquo

table_name | table_schema--------------+--------------test | publicpg_ts_dict | publicpg_ts_parser | publicpg_ts_cfg | publicpg_ts_cfgmap | publicbranches | publictellers | publichistory | publicaccounts | public

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 45 115

Export import datMoznosti

SQL dump tabulek a strukturySystemovym prıkazem pg dump dokazeme exportovat tabulku (nebo vıcetabulek) a to jak data tak strukturu Vysledny soubor obsahuje SQL prıkazyData lze ulozit jako sadu prıkazu INSERT nebo jako jeden prıkaz COPY

COPY na serveruTento prıkaz vytvorı (precte) textovy soubor (hodnoty oddelene carkou nebotabelatorem) ulozeny na serveru Pri zpracovanı nedochazı k prenosu dat posıti Musıme mıt k dispozici prostor na serveru prıstupny pro uzivatelepostgres

COPY z klientaObdoba prıkazu COPY implementovana jako prıkaz konzole psql Cte (uklada)soubory na stranne klienta zajistuje prenos dat po sıti a zpracovanı na straneserveru Format souboru je stejny jako na u prıkazu COPY na serveru

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 46 115

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 24: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Export import datMoznosti

file fdwPouzitı tzv externıho datoveho zdroje - foreign Data Wrapper - umoznujedotazy na data ulozena mimo SQL server Jednım z dostupnych ovladacu jefile fdw umoznujıcı cıst data ze souboru (ve stejnem formatu jako prıkazCOPY) K dispozici jsou ovladace pro MySQL Oracle ODBC Data lzepouze cıst

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 47 115

Export import datpg dump

pg_dump [OPTION] [DBNAME]-a --data-only pouze data-c --clean predradı prıkazy pro zrusenı

objektu-C --create vlozı prıkazy k vytvorenı

objektu-d --inserts pouzije INSERT mısto COPY-E --encoding=ENCODING pouzije urcene kodovanı-s --schema-only pouze schema--disable-triggers po dobu nacıtanı dat blokuje

triggery-t --table=TABLE pouze urcitou tabulku

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 48 115

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 25: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Export import datCOPY

COPY tablename [ ( column [ ] ) ](FROM|TO) filename | (STDIN|STDOUT) [ [ WITH ]

[ BINARY ][ HEADER ][ OIDS ][ DELIMITER [ AS ] delimiter ][ NULL [ AS ] null string ][ CSV [ HEADER ]

[ QUOTE [ AS ] quote ][ ESCAPE [ AS ] escape ][ (FORCE NOT NULL column [ ]|

FORCE QUOTE column [ ]) ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 49 115

Export import datfile fdw

postgres= CREATE EXTENSION file_fdwCREATE EXTENSION

postgres= CREATE SERVER file_serverFOREIGN DATA WRAPPER file_fdw

CREATE SERVER

postgres= CREATE FOREIGN TABLE tbl (a int b int c int)SERVER file_serverOPTIONS (format csv filename tmphodnotycsv)

CREATE FOREIGN TABLE

postgres= SELECT FROM tbl where a gt 10a | b | c----+----+----40 | 50 | 6070 | 80 | 90(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 50 115

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 26: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Export import datEfektivita

Prehled jednotlivych metodUvedena tabulka obsahuje udaje o importu jednoho milionu radekjednosloupcove celocıselne tabulky (testovano na notebooku Prestigio Nobile156 P16 500M)

Metoda Velikost CasINSERTS (autocommit on) 378 M 10 minINSERTS (autocommit off) 378 M 22 minCOPY 68 M 10 secCOPY (UDP) 68 M 10 secCOPY BINARY 10 M 7 secCOPY (+ 1 index) 68 M 17 sec

ZaverPreferovat COPYZrusit vsechny indexy (nejsnaze pomocı SQL procedury)zablokovat triggery (ALTER TABLE name DISABLE TRIGGER ALL)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 51 115

Zalohovanı obnova databazePrehled

Prehled technik zalohovanıK dispozici jsou tri zpusoby zalohovanı

SQL dump prıkazy pg dump pg restore Data lze ulozit jako SQL skriptnebo v specialnım komprimovanem formatuzaloha na urovni souboroveho systemu Server musı byt zastaven Lzezalohovat a obnovovat pouze kompletnı db clustertar -cf backuptar usrlocalpgsqldataonline zalohovanı je zalozeno na tzv write ahead logu (WAL) coz jesoubor do ktereho se zapisujı vsechny zmeny v datech jeste predtım nezse zapısı do datovych souboru Primarne tento log slouzı k obnovedatabaze po havarii muzeme jej vsak exportovat ulozit a pouzıt provytvorenı zalohy

jedine mozne resenı prubezneho zalohovanınarocne na diskovy prostornarocne na administracizalohovanı i obnova je velice rychlezaloha nenı kompatibilnı mezi 32 a 64 bit platformami

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 52 115

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 27: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Zalohovanı obnova databazeVytvorenı zalohy exportovanım WAL

Postup1 V postgresqlconf nastavıme archive command Tento prıkaz zajistı

prenesenı segment logu na bezpecne medium PostgreSQL neodstranısegment dokud prıkaz neprobehne bezchybne

archive_command = cp -i p mntserverarchivedirf2 Export logu aktivujeme volanım select pg start backup(rsquonavestirsquo)

Jako navestı muzeme pouzıt libovolny retezec napr cesta k zaloze3 V tomto prıpade muzeme bezpecne za chodu zkopırovat obsah dovoheho

adresare PostgreSQL Nenı treba zalohovat adresar pg xlog4 po dokoncenı kopırovanı deaktivujeme export logu volanım SELECT

pg stop backup() Export logu muze bezet libovolnou dobu coz je zakladprubezneho zalohovanı

Prubezne zalohovanıSegment se exportuje po naplnenı (16MB) nebo po prednastavenem casovemintervalu (82) Efektivne jej lze komprimovat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 53 115

Zalohovanı obnova databazeObnova ze zalohy exportovaneho WAL

Postup1 Zazalohujte si aktualnı cluster (vcetne pg xlog)2 Prekopırujte data ze zalohy (zazalohovany datovy adresar)3 Upravte soubor recoveryconf a ulozte jej v adresaru clusteru Vzor

naleznete v podadresari shared Minimalnı zmenou je nastavenı polozkyarchive command

4 do nadresare pg xlog zkopırujte vsechny nezazalohovane soubory zadresare pg xlog (to jsou WAL segmenty ktere vznikly po deaktivaciexportu)

5 Nastartujte server Pri startu se automaticky spustı proces obnovy nazaklade WAL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 54 115

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 28: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Sprava uzivatelucreateuser

Usagecreateuser [OPTION] [ROLENAME]

Options-s --superuser role will be superuser-S --no-superuser role will not be superuser-d --createdb role can create new databases-D --no-createdb role cannot create databases-r --createrole role can create new roles-R --no-createrole role cannot create roles-l --login role can login (default)-L --no-login role cannot login-i --inherit role inherits privileges of roles it is a

member of (default)-I --no-inherit role does not inherit privileges-c --connection-limit=N connection limit for role (default no limit)-P --pwprompt assign a password to new role-E --encrypted encrypt stored password-N --unencrypted do not encrypt stored password-e --echo show the commands being sent to the server-q --quiet dont write any messages

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 55 115

Sprava uzivateluCREATE ROLE

Command CREATE ROLEDescription define a new database roleSyntaxCREATE ROLE name [ [ WITH ] option [ ] ]

where option can be

SUPERUSER | NOSUPERUSER| CREATEDB | NOCREATEDB| CREATEROLE | NOCREATEROLE| CREATEUSER | NOCREATEUSER| INHERIT | NOINHERIT| LOGIN | NOLOGIN| CONNECTION LIMIT connlimit| [ ENCRYPTED | UNENCRYPTED ] PASSWORD password| IN ROLE rolename [ ]| ROLE rolename [ ]| ADMIN rolename [ ]| USER rolename [ ]| SYSID uid

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 56 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 29: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Sprava uzivateluVyklad

Pravidla chovanı rolı IZavislosti mezi rolemi tvorı orientovany graf ktery nesmı obsahovat cyklus(Pavel muze zıskat prava Tomase zaroven ale Tomas nemuze zıskatprava Pavla)Uzivatel zıska prava rolı jejichz je clenem (ke kterym ma prıstup kteremuze prevzıt)

CREATE ROLE tom_a_pavel IN ROLE tom pavelRole tom a pavel muze prevzıt roli Tomase nebo Pavla (je to nadrazenarole temto rolım) a ma prava jako Tomas a Pavel dohromadyRoli muzeme definovat take tak ze urcıme kdo tuto roli muze pouzıvat

CREATE ROLE developer ROLE tom pavelRoli developer muze pouzıt jako Tomas tak Pavel Pokud ma role atributINHERIT tak automaticky zıskava prava vsech rolı jejichz je clenem (kteremuze pouzıt) Bez tohoto atributu vyvojar musı explicitne aktivovat roliprıkazem SET ROLE developer

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 57 115

Sprava uzivateluVyklad

Pravidla chovanı rolı IIUzivatel muze zmenit vlastnictvı objektu ke kterym ma prava prıkazem

ALTER TABLE objekt OWNER TO developerale nemuze se vzdat svych prav tj nemuze zmenit vlastnictvı tak abyprisel o objekt (nelze databazovy objekt darovat nekomu neznamemu snımz nemam nic spolecneho

RekapitulaceCREATE ROLE vytvorı novou roliGRANT co TO komu delegovanı urciteho prava roliGRANT r1 TO r2 role r2 zıskava stejna prava jako ma role r1

REVOKE odejmutı pravALTER TABLE OWNER TO zmena vlastnictvı objektu

dg zobrazenı rolı a clenstvı v psql

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 58 115

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 30: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Konfigurace databazeVolba souboroveho systemu

Vliv souboroveho systemu na vykon databazeNelze obecne rıci ktery souborovy system je optimalnı Pri umelych testechbylo poradı souborovych systemu nasledujıcı JFS ext2 Reiser3 ext3 XFSRozdıl mezi nejpomalejsı a nejrychlejsı testovacı konfiguracı byl 30 (coz senebere jako natolik vyznamna hodnota aby se o tom prılis diskutovalo) Urdquohighrdquo radicu je nutne explicitne povolit write cache (bateriı zalohovane radice)

Zaverpouzıvejte takovy souborovy system ktery je pro vas duveryhodny (RAID10)na UNIXech pouzıvejte mount parametr noatimepokud jste jisteni UPS lze pro ext3 pouzıt mount parametrdata=writeback vykonove se dostanete na uroven ext2 v zadnemprıpade se nedoporucuje zmenit konfiguracnı parametr fsync na offpokuste se umıstit WAL na jiny nejlepe RAID 1 disk nez data (symlink) verifikujte konfiguraci testem pgbench ktery by mel zobrazovat ramcovesrovnatelne hodnoty s jinou instalacı PostgreSQL na podobnem hw

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 59 115

Konfigurace databazePridelenı pameti

StrategiePostgreSQL ma mıt prideleno maximum pameti aniz by zpomalila osPridelenı pameti je urceno hodnotami urcitych parametru v postgresqlconfPouze parametr work mem lze nastavovat dynamicky Neexistuje uplna shodaohledne doporucenych hodnot

postgresqlconf Ishared buffers velikost cache pro systemove objekty [322048] MB

(625)work mem velikost alokovane pracovnı pameti pro kazde spojenı omezuje

pouzitı diskove mezipameti pri operaci sort urcuje maximalnıvelikost hash tabulek pri operaci hash join lze ji nastavitdynamicky pred narocnym dotazem [110] MB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 60 115

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 31: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Konfigurace databazePridelenı pameti

postgresqlconf Imaintenance work mem velikost pameti pouzıvane pro prıkazy jako jsou

VACUUM nebo CREATE INDEX Jelikoz nenı pravdepodobne ze bydoslo k soubehu provadenı techto prıkazu lze bezpecne tutohodnotu nastavit vyrazne vyssı nez je work mem Doporucuje se32 256MB nebo 5075 velikosti nejvetsı tabulky

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 61 115

Konfigurace databazeParametrizace planovace dotazu

PoznamkaAz na vyjimky parametry tykajıcı se vyberu nejvhodnejsıho zpusobu provadenıdotazu jsou urcene pouze pro vyvojare PostgreSQL a majı umoznit vzdalenoudiagnostiku nahlasenych problemu

postgresqlconf IIefective cache size predpokladana velikost celkove diskove vyrovnavacı

pameti pouzite pro jeden dotaz (vcetne shared buffersPostgreSQL a casti sys cache pouzite pro soubory PostgreSQL)Pozor na soubezne dotazy z ruznych tabulek ktere se musı vejıtdo dostupneho prostoru Tato hodnota nesouvisı se skutecnoupotrebou pameti Vyssı hodnota znamena preferenci indexu(vyssı pravdepodobnost ze cenove narocnejsı index nalezneme vcache) Nizsı preferenci sekvencnıho ctenı tabulky Vychozınastavenı je 128 M V Linuxu RAM - os - ostatnı aplikace (Linuxagresivne pouzıva cache)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 62 115

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 32: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Konfigurace databazeParametrizace procesu autovacuum

Strategie

Castejsı provedenı prıkazu VACUUM nez je nutne je mensım zlem neznedostatecne caste provadenı tohoto prıkazu Spoustı se periodicky (cron)nebo pri prekrocenı dynamicke prahove hodnoty (autovacuum) Tato hodnotaroste s velikostı tabulky

postgresqlconf IIIstats row level aktualizace provoznıch statistikautovacuum povolenı samotneho procesu (vyzaduje provoznı statistiky)

Prıkaz VACUUM se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum vacuum threshold + (autovacuum vacuum scale factor lowastvelikost tabulky) Priblizne 20 poctu radek v tabulcePrıkaz ANALYZE se spustı pokud pocet modifikovanych radku je vetsı nezautovacuum analyze threshold + (autovacuum analyze scale factor lowastvelikost tabulky) Priblizne 10 poctu radek v tabulce

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 63 115

Monitorovanı databazeSledovanı aktivity

Pohled do systemovych tabulekpohled pg stat activity obsahuje prehled cinnosti prihlasenych klientupohled pg stat database obsahuje pocet prihlasenych klientu kjednotlivym databazımpohled pg stat all tables obsahuje provoznı statistiky tabulekpohled pg stat all indexes obsahuje provoznı statistiky indexupohled pg locks obsahuje seznam aktivnıch zamku

postgresqlconf IVSledovanı deletrvajıcıch a chybnych dotazulog min error statement = error loguje vsechny chybne SQL prıkazylog min duration statement = 200 loguje vsechny SQL prıkazy provadene

dele nez 200msNa vytezenı udaju z logu lze pouzıt tzv PostgreSQL log analyzer pgFouine

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 64 115

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 33: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Monitorovanı databazeSledovanı aktivity

postgresqlconf VSledovanı prıkazu cekajıcıch na uvolnenı zamkulog lock waits = on loguje vsechny SQL prıkazy cekajıcı dele nez je test na

deadlock

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 65 115

Monitorovanı databazeZjistenı obsazeneho prostoru databazovymi objekty

-- setrıdeny vypis seznamu databazı podle velikostiroot= select datname pg_size_pretty(pg_database_size(datname))

from pg_databaseorder by pg_database_size(datname) desc

datname | pg_size_pretty------------+----------------root | 168 MBpostgres | 4088 kBregression | 3864 kB

-- setrıdeny vypis tabulek v databazi podle velikostiroot= select nnspname crelname pg_size_pretty(pg_total_relation_size(coid))

from pg_class c left join pg_catalogpg_namespace n on noid = crelnamespacewhere crelkind = rorder by pg_total_relation_size(coid) desclimit 10

Schema | relname | pg_size_pretty------------+----------------+----------------root | test_data | 138 MBpublic | accounts | 25 MBpg_catalog | pg_proc | 864 kBpg_catalog | pg_depend | 744 kBpg_catalog | pg_attribute | 536 kBpublic | history | 344 kB

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 66 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 34: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- funkce pgstattuple a pgstatindex z balıcku pgstattuplepostgres= xExpanded display is onpostgres= select from pgstattuple(foo)-[ RECORD 1 ]------+------table_len | 8192tuple_count | 0tuple_len | 0tuple_percent | 0dead_tuple_count | 2dead_tuple_len | 93dead_tuple_percent | 114free_space | 8064free_percent | 9844

postgres= select from pgstatindex(foox)-[ RECORD 1 ]------+-----version | 2tree_level | 0index_size | 8192root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 093leaf_fragmentation | 0

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 67 115

Monitorovanı databazeMonitorovanı podılu mrtvych zaznamu a fragmentace indexu

-- 30 mrtvych zaznamu ma znatelny vliv na rychlost provadenı dotazuSELECT schema name (st)tuple_count pg_size_pretty((st)table_len) AS table_len

(st)dead_tuple_count (st)dead_tuple_percentpg_size_pretty((st)free_space) AS free_space

FROM (SELECT nnspname AS schema crelname AS name pgstattuple(coid) AS st

FROM pg_catalogpg_class cLEFT JOINpg_catalogpg_namespace nON noid = crelnamespace

WHERE crelkind in (r) and pg_catalogpg_table_is_visible(coid)) s

-- optimalnı vyuzitı je 60-70 koncovych stranekSELECT schema table name pg_size_pretty((st)index_size) AS index_size

(st)internal_pages AS internal (st)leaf_pages as leaf(st)empty_pages AS empty (st)deleted_pages AS deleted (st)avg_leaf_density AS avg_leaf (st)leaf_fragmentation AS leaf_frag(st)tree_level

FROM (SELECT schemaname AS schema tablename AS table indexname AS name

pgstatindex(schemaname || || indexname) AS stFROM pg_indexes

) s

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 68 115

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 35: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Monitorovanı databazeMonitorovanı obsahu sdılene vyrovnavacı pameti

SELECT crelname count() AS buffersFROM pg_class c INNER JOIN pg_buffercache b

ON brelfilenode = crelfilenode INNER JOIN pg_database dON (breldatabase = doid AND ddatname = current_database())

GROUP BY crelnameORDER BY 2 DESC LIMIT 10

relname | buffers---------------------------------+---------tenk2 | 345tenk1 | 141pg_proc | 46(10 rows)

PoznamkaObsah cache by mel byt pokud mozno stabilnı Pokud se casto menıznamena to intenzivnı zatızenı IO operacemi (sekvencnı ctenı velkychtabulek) Muze souviset s nevhodnym nastavenım effective cache size

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 69 115

Instalace doplnkuPostup

PoznamkaPostgreSQL je navrhovan minimalisticky tj co nemusı byt castı jadrapresouva se do rozsirujıcıch (contrib) modulu Prıkladem muze byt tsearch2fuzzystrmatch pgcrypto nebo pgbench Ukazka obsahuje instalaci doplnkuorafce coz je sada funkcı inspirovana knihovnou RDBMS Oracle

1 Pokud jste v adresari contrib make make install2 V privatnım adresari make USE PGXS=1 make USE PGXS=1 install3 Jako superuser provest prıkaz CREATE EXTENSION

CREATE EXTENSION orafce4 U nekterych doplnku je nutne explicitne zprıstupnit nove funkce prıkazem

GRANT Tımto zpusobem urcujeme kdo smı nove funkce pouzıvat

pgbenchpgbench je jednoducha klientska aplikace ktera generuje unifikovanou zatezserveru PostgreSQL V podstate nelze jednoznacne interpretovat vyslednouhodnotu udavajıcı pocet realizovanych zakaznickych transakcı za vterinu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 70 115

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 36: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Instalace doplnkuTestovanı

Regresnı testKazdy doplnek obsahuje sadu testu umoznujıcıch alespon ramcove overitfunkcnost na dane platforme Pokud selze regresnı test reportujte popis chybya platformy spravci testovaneho doplnku

make USE_PGXS installcheck

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 71 115

Instalace doplnkuPostup

postgres= dxList of installed extensions

Name | Version | Schema | Description---------+---------+------------+------------------------------plpgsql | 10 | pg_catalog | PLpgSQL procedural language(1 row)

postgres= select from pg_available_extensions()name | default_version | comment

----------+-----------------+---------------------------------------------xx | 10 | data type for multidimensional cubesplperl | 10 | PLPerl procedural languageunaccent | 10 | text search dictionary that removes accentsplperlu | 10 | PLPerlU untrusted procedural languageplpgsql | 10 | PLpgSQL procedural language(5 rows)

postgres= CREATE EXTENSION unaccentCREATE EXTENSION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 72 115

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 37: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Postup pri prechodu na novou verziPlan

PoznPri minoritnı zmene (zmena za destinou teckou) jsou verze datove kompatibilnı(tudız stacı pouze zmenit binarnı soubory) Pri aktualizaci mezinekompatibilnımi verzemi je treba provest dump databaze V prıpade kdybudeme migrovat na novejsı verzi je doporucovano aby dump byl provedemprıkazem pg dump z novejsı verze (tj nejdrıve aktualizujeme klientske aplikacepote server vsechny PostgreSQL aplikace se dokazou pripojit k serveru jineverze (pouze dostanete varovanı)) Aktualnı verze dokazı nacıst dump zpg dump verze 70

TipMigraci muzeme zkratit paralelnım provozem noveho serveru na jinem portu amigracı pres rouru

pg_dumpall -p 5432 | psql -d postgres -p 6543

Overte si ze Vam nikdo v te dobe nepristupuje k SQL serverum

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 73 115

Postup pri prechodu na novou verziMozne problemy

Migraci vzdy testujteJeste pred dumpem v novejsı verzi vytvorete zalohu v aktualnı verzi Nenızaruceno ze se starsı klient dokaze pripojit k novejsımu serveru tj bezteto zalohy by cesta zpet mohla byt obtıznaProstudujte si odpovıdajıcı RELEASE NOTESV idealnım prıpade mate k dispozici UNIT testyUpgrade prılis neodkladejte je jistejsı udelat nekolik mensıch kroku nezjeden skok Nove verze PostgreSQL vychazejı jednou rocne Zarucenepodporovane jsou dve verze zpatky (oprava chyb bezpecnostnı zaplatyatd) Jako optimalnı je upgrade kazde dva roky

Kde mohou nastat problemyodstranenı rizikovych implicitnıch typovych konverzı v 83 integracefulltextuprısnejsı kontrola UTF8 ve verzi 82 (tj predchozı dump muze bytpovazovan za nekorektnı) Oprava - pouzitı filtru iconvprılis stara verze PostgreSQL (73 a starsı) - provadejte upgradeinkrementalne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 74 115

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 38: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Postup pri prechodu na novou verziZrychlenı nactenı dumpu

TipNacıtanı dump souboru lze urychlit docasnym prenastavenım nıze urcenychkonfiguracnıch parametru Tyto hodnoty jsou urcene pouze pro nacıtanı dat(predpokladajı jednouzivatelsky rezim) ktere lze v prıpade problemu opakovata nejsou urcene pro produkcnı rezim

fsync = offshared_buffers = [13 of memory]wal_buffers = 1MBcheckout_timeout = 1hcheckpoint_segments = 300maintenance_work_mem = [13 of memory]

Nezapomente ze pro upgrade potrebujete minimalne 2x tolik volnehoprostoru jako je aktualnı velikost datoveho adresare Po dokoncenı importunezapomente konfiguraci nastavit na provoznı hodnoty fsync = off muze vestke ztrate dat

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 75 115

Postup pri prechodu na novou verzipg upgrade

TipPro upgrade vetsıch databazı je mozne pouzıt prıkaz pg upgrade Je vyraznerychlejsı nez upgrade pomocı pg dump navıc s volbou --link nedochazı kekopırovanı souboru (Pozor po startu nove verze uz nikdy nelze nad stejnymidaty nastartovat puvodnı verzi)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 76 115

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 39: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Efektivnı SQLChybne pouzitı UNION

PoznJe chybou pouzıvat UNION nad jednou tabulkou

SELECT H cena cena105FROM TovarWHERE typ = sz AND cena lt 100UNIONSELECT C cena cena122FROM TovarWHERE typ = dz AND cena lt 100UNIONSELECT O cena cena13FROM TovarWHERE (cena gt= 100) OR (typ ltgt dz)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 77 115

Efektivnı SQLSpravne pouzitı CASE

PoznVzhledem k tomu ze CASE vracı record je nutne jej rozvinout pomocı odvozene tabulky ROW jeanonymnı konstruktor radku Poto je nutne pretypovanı

CREATE TYPE nk AS (tp char(1) koef float)SELECT (sp)tp scena (sp)koefscenaFROM

(SELECT CASE WHEN typ = sz AND cena lt 100 THEN ROW(H105)nkWHEN typ = dz AND cena lt 100 THEN ROW(C122)nkELSE ROW(O133)nk END cena

FROM Tovar) AS s(pcena)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 78 115

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 40: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Efektivnı SQLNepouzıvejte ALL

PoznPri psanı vnorenych dotazu lze chytre pouzıt agregacnı funkce MIN a MAX Nasledujıcıdotazy jsou funkcne ekvivalentnı Druhy dotaz je ovsem radove (1000x) rychlejsı

SELECT FROM aWHERE a gt ALL

(SELECT b FROM b)

SELECT FROM aWHERE a gt

(SELECT MAX(b) FROM b)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 79 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

PoznPro tabulky Produkt a Polozka (kardinalita 1n) zobrazı 10 nejvetsıch jednorazovychprodeju

SELECT FROM

(SELECT nazev(SELECT MAX(kusu)

FROM PolozkaWHERE produkt_id = pid

) AS kusuFROM Produkt p

) dWHERE dkusu IS NOT NULLORDER BY dkusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 80 115

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 41: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Efektivnı SQLKorelovany dotaz v klauzuli SELECT nahradte spojenım s odvozenou tabulkou

Vyhodycitelnejsınevyzaduje index na tab polozka(produkt id)2-3x rychlejsı

SELECT nazev kusuFROM Produkt pr

INNER JOIN(SELECT MAX(kusu) AS kusu produkt_id

FROM PolozkaGROUP BY produkt_id

) AS poON prid = poprodukt_id

ORDER BY kusu DESCLIMIT 10

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 81 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı objednavky Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 82 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 42: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Efektivnı SQLNicmene svet nenı jednoduchy

PoznTento dotaz je opet o neco citelnejsı a cca 3x rychlejsı Stacı ale jedina zmena

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_id

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 83 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznZobrazı 20 nejnovejsıch objednavek Zdrojem jsou tabulky Zakaznik a Faktura

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOINFaktura fON zid = fzakaznik_id

WHERE fvlozeno =(SELECT MAX(vlozeno)

FROM FakturaWHERE zakaznik_id = zid

)ORDER BY fvlozeno DESCLIMIT 20

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 84 115

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 43: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Efektivnı SQLNicmene svet nenı jednoduchy

PoznPo pridanı LIMIT 20 je korelovany dotaz v klauzuli WHERE cca 40x rychlejsı

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaGROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 85 115

Efektivnı SQLNicmene svet nenı jednoduchy

ResenıZmena zadanı 20 nejnovejsıch objednavek v mesıci prosinec 2009 Cılem je navrhnoutGUI tak aby poskytovalo dostatek indiciı pro rychle dotazy

SELECT znazev fvlozenoFROM Zakaznik z

INNER JOIN(SELECT MAX(vlozeno) AS vlozeno zakaznik_id

FROM FakturaWHERE vlozeno BETWEEN rsquo2009-11-01rsquo AND last_day(rsquo2009-11-01rsquo)GROUP BY zakaznik_idORDER BY vlozeno DESCLIMIT 20

) fON zid = fzakaznik_id

ORDER BY fvlozeno DESC

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 86 115

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 44: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

IndexyTypy

Podporovane typyjednoduchy index jeden sloupecslozeny index vıce sloupcucastecny index pouze nad castı tabulkyfunkcnı index nad vysledkem funkce

Podporovane formatyB-treeHashGiST a GiN

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table[ USING method ]( column | ( expression ) [ opclass ] [ ] )[ TABLESPACE tablespace ][ WHERE predicate ]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 87 115

IndexyUkazka funkcnıho a castecneho indexu

ZadanıUrychlete vyhledavanı uzivatelu na zaklade zadanı casti domenove adresynapr rdquocvutczrdquo Pouze tretina uzivatelu ma emailovou adresu

PoznIndex se v LIKE pouzije pouze tehdy pokud maska nezacına zolıkem Proto jenutne pouzıt trik s revertovanım adresy cs CZ locales si vynucuje pouzitıopclass Predikatem (castecny index) zvysujeme selectivitu indexu LIKE jecase sensitive operace

CREATE UNIQUE INDEX idx_users_emailON users((plvstrrvrs(email)) varchar_pattern_ops)WHERE email IS NOT NULL

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 88 115

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 45: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

IndexyZaver

Doporucenıindexy navrhujte pouze na sloupce s dostatecnou selectivitoudobrymi kandidaty na index jsou sloupce cizıch klıcu a sloupce proagregacnı funkce MAX a MINnepouzıvane indexy odstrantepreferujte jednoduche indexyindexy navrhujte pouze pro tabulky s vıce nez 1000 radky (nemajı smysl)pri zmene charakteru dat vzdy aktualizujte datove statistikycca jednou mesıcne (zalezı na frekvenci zmen v databazi) reindexujtedatabaziv prıpade velkych tabulek zvazte prınos partitioningu

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 89 115

Optimalizace dotazuPar rad

Doporucenıoptimalizujte caste nebo extremne pomale dotazypred kazdou optimalizacı nezapomente na VACUUM ANALYZEpredikaty zapisujte tak aby jednu stranu zapisu tvoril pouze atributz vypisu provadecıho planu urcete smysl prıpadnych novych indexupokud se z nejakeho duvodu nepouzije index zkusteset enable seqscan to offpokud toto resenı pomuze zkuste zvetsit pocet trıd datoveho histogramusloupce indexu (ma smysl u specifickych rozdelenı)ALTER TABLE ALTER COLUMN SET STATISTICSprepiste dotaz (EXISTS IN JOIN )

PoznNenı chybou kdyz se nepouzije index v prıpade ze se jedna o malou tabulkunebo se z tabulky cte vıce nez 30 radku Pokud si nejste jisti penalizujtesekvencnı ctenı prıkazem set enable seqscan to off

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 90 115

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 46: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Optimalizace dotazuNeoptimalnı plan chybı index Faktura(zakaznik id)

QUERY PLAN----------------------------------------------------------------------------------------------------Limit (cost=74428635527442863554 rows=10 width=149)

-gt Sort (cost=74428635527442863630 rows=312 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0007442862259 rows=312 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000103663 rows=62363 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=119332119333 rows=1 width=4)-gt Seq Scan on faktura(cost=000119254 rows=312 width=4)

Filter (zakaznik_id = $0)(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 91 115

Optimalizace dotazuLepsı plan vytvoren index Faktura(zakaznik id)

QUERY PLAN------------------------------------------------------------------------------------------------------------------Limit (cost=27081645892708164591 rows=10 width=149)

-gt Sort (cost=27081645892708164670 rows=324 width=149)Sort Key fvlozeno-gt Nested Loop (cost=0002708163238 rows=324 width=149)

Join Filter (fvlozeno = (subplan))-gt Seq Scan on faktura f (cost=000106023 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z(cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan

-gt Aggregate (cost=4182741828 rows=1 width=4)-gt Bitmap Heap Scan on faktura (cost=64441746 rows=324 width=4)

Recheck Cond (zakaznik_id = $0)-gt Bitmap Index Scan on idx_faktura_zakaznik_id(cost=000644 rows=324 width=0)

Index Cond (zakaznik_id = $0)(14 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 92 115

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 47: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Optimalizace dotazuDobry plan pridan index Faktura(vlozeno)

QUERY PLAN-----------------------------------------------------------------------------------------------------------------------------Limit (cost=0002108684 rows=10 width=149)

-gt Nested Loop (cost=00068321369 rows=324 width=149)Join Filter (fvlozeno = (subplan))-gt Index Scan Backward using idx_faktura_vlozeno on faktura f(cost=000319885 rows=64723 width=8)-gt Index Scan using zakaznik_pkey on zakaznik z (cost=000011 rows=1 width=149)

Index Cond (zid = fzakaznik_id)SubPlan-gt Result (cost=10371038 rows=1 width=0)

InitPlan-gt Limit (cost=0001037 rows=1 width=4)

-gt Index Scan Backward using idx_faktura_vlozeno on faktura(cost=000336066 rows=324 width=4)

Filter ((vlozeno IS NOT NULL) AND (zakaznik_id = $0))(12 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 93 115

SekvenceSchema

Popisgenerujı rostoucı posloupnost jedinecnych cıselpouzıvajı se jako jedinecne kody v ramci db nebo PKvıceuzivatelsky bezpecne

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 94 115

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 48: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

SekvenceSeznam funkcı

Funkce pro operace nad sekvenceminextval zvysı aktualnı hodnotu sekvence a tuto hodnotu vratı krome toho

zkopıruje tuto hodnotu do lokalnıho bufferu sekvencecurrval vracı hodnotu ulozenou v lokalnım bufferu sekvencelastval vracı hodnotu lokalnıho bufferu naposledy aktualizovane

sekvencesetval nastavı hodnotu sekvence

PoznTyp serial pro uzivatele transparentne automatizuje veskere operacepotrebne pro pouzitı sekvencı v PK (analogie typu identity z jinych RDBMS)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 95 115

SekvenceTyp serial

postgres=gt create table foo(pk serial primary key)NOTICE CREATE TABLE will create implicitsequence lsquolsquofoo_pk_seqrsquorsquo for serial column lsquolsquofoopkrsquorsquoNOTICE CREATE TABLE PRIMARY KEY will createimplicit index lsquolsquofoo_pkeyrsquorsquo for table lsquolsquofoorsquorsquoCREATE TABLEpostgres=gt foo

Table lsquolsquopublicfoorsquorsquoColumn | Type | Modifiers--------+---------+--------------------------------------------------pk | integer | not null default nextval(rsquofoo_pk_seqrsquoregclass)Indexes

lsquolsquofoo_pkeyrsquorsquo PRIMARY KEY btree (pk)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 96 115

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 49: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Integrovany fulltextInstalace

-- Soubory czechaffix czechdict a czechstop rozbalte-- a presunte do adresare sharetsearch_dataCREATE TEXT SEARCH DICTIONARY cspell

(template=ispell dictfile = czech afffile=czechstopwords=czech)

CREATE TEXT SEARCH CONFIGURATION cs (copy=english)

ALTER TEXT SEARCH CONFIGURATION csALTER MAPPING FOR word asciiword WITH cspell simple

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 97 115

Integrovany fulltextVerifikace

postgres= select from ts_debug(rsquocsrsquorsquoPrılis zlutoucky kun se napil zlute vodyrsquo)alias | description | token | dictionaries | dictionary | lexemes

-----------+-------------------+-----------+-----------------+------------+-------------word | Word all letters | Prılis | cspellsimple | cspell | prılisblank | Space symbols | | | |word | Word all letters | zlutoucky | cspellsimple | cspell | zlutouckyblank | Space symbols | | | |word | Word all letters | kun | cspellsimple | cspell | kunblank | Space symbols | | | |asciiword | Word all ASCII | se | cspellsimple | cspell | blank | Space symbols | | | |asciiword | Word all ASCII | napil | cspellsimple | cspell | napıtblank | Space symbols | | | |word | Word all letters | zlute | cspellsimple | cspell | zlutyblank | Space symbols | | | |asciiword | Word all ASCII | vody | cspellsimple | cspell | voda(13 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 98 115

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 50: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Integrovany fulltextPouzitı - vytvorenı fulltextoveho indexu

CREATE TABLE fulltext_test(zdroj text nazev text)

set content rsquorsquorsquo lsquosed -e lsquolsquosrsquorsquogrsquorsquo lt ~postgresdotazyhtmllsquo rsquorsquorsquo

INSERT INTO fulltext_test VALUES(content rsquoKorelovane poddotazyrsquo)

CREATE INDEX pgweb_idx ON fulltext_testUSING gin(to_tsvector(rsquocsrsquo zdroj))

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 99 115

Integrovany fulltextPouzitı - pouzitı fulltextoveho vyhledavanı

postgres= SELECT nazev ts_headline(rsquocsrsquo zdroj to_tsquery(rsquocsrsquo rsquoefektivnı amp dotazrsquo))

FROM fulltext_testWHERE to_tsvector(rsquocsrsquozdroj) to_tsquery(rsquocsrsquorsquoefektivnı amp dotazrsquo)

ts_headline

nazev | ts_headli----------------------+---------------------------------------------------------------------Korelovane poddotazy | ltbgtdotazyltbgt ltbgtefektivneltbgt nahradit Pozn v rade aplikacı jsouLeft inner join | ltbgtdotazltbgt

vyzaduje vsechny sloupce tabulky pak je to v poradku To vsak v prı vetsinou nebyva tak uplne pravda a tudız zpracovanı prıkazu nenı ta

(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 100 115

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 51: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Integrovany fulltextVyhledavanı na zaklade prefixu

PopisFulltext umoznuje specifikovat hledana slova prefixem

postgres= select from codebookspsc_obcewhere to_tsvector(rsquosimplersquo cast_obce)

to_tsquery(rsquosimplersquo rsquoBenersquo)obec | psc | nazev_posty | lau1

-----------------------+-------+-----------------------+-------Benecko | 51237 | Benecko | CZ0514Benecko | 51401 | Jilemnice | CZ0514Busanovice | 38422 | Vlachovo Brezı | CZ0315Broumov | 55001 | Broumov 1 | CZ0523Benesov | 25601 | Benesov u Prahy | CZ0201Benesov | 67953 | Benesov u Boskovic | CZ0641

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 101 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

PopisVyhledavanı na zaklade castecne shody nelze urychlit indexem Pomerneuspesne lze pouzıt vyhledavanı pomocı podobnosti trigramu retezcu

Vyhoda lze indexovatNevyhoda nutno nastavovat limit (cım delsı retezec tim vıc moznychtrigramu tım vyssı mıra podobnosti tım vyssı nezbytny limit

V nasledujıcım prıkladu pouzıvam trigram vyhledavanı pro urychlenı vyhledanıv cıselnıku obcı - hledam PSC

postgres= SELECT show_trgm(Benesov)show_trgm

----------------------------------------- b bebeneneesonesov sov

postgres= CREATE INDEX trgm ON pscUSING gin(replace(obec ) gin_trgm_ops)

CREATE INDEX

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 102 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 52: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= SELECT FROM psc WHERE replace(obec ) benesovobec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Bezverov | 03016 | 03 | 33041Unesov | 03016 | 03 | 33038

postgres= EXPLAIN ANALYZE SELECT FROM psc WHERE replace(obec ) benesovQUERY PLAN

---------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291728 rows=4 width=30)(actual time=22363227 rows=11 loops=1)Preread target 64Filter (replace((obec)text text text) benesovtext)-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)

(actual time=18661866 rows=130 loops=1)Index Cond (replace((obec)text text text) benesovtext)

Total runtime 3384 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 103 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= EXPLAIN ANALYZE select FROM psc WHERE (obec ilike benesov)QUERY PLAN

-------------------------------------------------------------------------------------------------Seq Scan on psc (cost=00010940 rows=1 width=30)(actual time=108320058 rows=9 loops=1)Filter ((obec)text ~~ benesovtext)

Total runtime 20146 ms(3 rows)

postgres= SELECT FROM psc WHERE (obec ILIKE benesov)obec | okres | kraj | pscn

-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 104 115

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 53: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Vyhledavanı na zaklade podobnostiModul pg tgrm

postgres= PREPARE filter(varchar) ASSELECT

FROM pscWHERE replace(obec ) $1

AND obec ilike ||$1||PREPAREpostgres= EXECUTE filter(benesov)

obec | okres | kraj | pscn-----------------------+-------+------+-------Kozmice u Benesova | 01093 | 01 | 25725Bystrice u Benesova | 01083 | 01 | 25751Benesov u Prahy | 01064 | 01 | 25601Benesov nad Cernou | 02027 | 02 | 38282Benesov nad Ploucnici | 04011 | 04 | 40722Benesov u Boskovic | 06079 | 06 | 67953Dolni Benesov | 07061 | 07 | 74722Horni Benesov | 09044 | 09 | 79312Benesov u Semil | 11005 | 11 | 51206(9 rows)

postgres= EXPLAIN ANALYZE EXECUTE filter(benesov)QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on psc (cost=4291731 rows=1 width=30) (actual time=42417319 rows=9 loops=1)

Preread target 64Filter ((replace((obec)text text text) ($1)text) AND ((obec)text ~~ ((text || ($1)text) || text)))-gt Bitmap Index Scan on trgm (cost=000429 rows=4 width=0)(actual time=40644064 rows=130 loops=1)

Index Cond (replace((obec)text text text) ($1)text)Total runtime 7494 ms(6 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 105 115

PoleUvod

Popisjasne porusujı prvnı normalnı formu (ale je atom skutecne nedelitelny)prakticky typ pro ukladanı casovych rad nezastupitelny v plpgsqlvsechny prvky pole musı byt jednoho typupole muze obsahovat NULL

postgres= select ARRAY[PavelTomas]array

-----------------PavelTomas(1 row)

postgres= select Pavel Tomasvarchar[]varchar

------------------------------Pavel Tomasvarchar[]

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 106 115

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 54: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

PoleOperace rozvinutı pole

postgres=gt CREATE OR REPLACE FUNCTION unnest(anyarray)postgres-gt RETURNS SETOF anyelement AS $$postgres$$gt SELECT $1[idxi]postgres$gt FROM generate_series(array_lower($11) array_upper($11))postgres$gt AS idx(i) $$postgres-gt LANGUAGE sql IMMUTABLECREATE FUNCTIONpostgres=gt SELECT unnest(ARRAY[123])unnest--------

123

(3 rows)

CREATE OR REPLACE FUNCTION unnest(anyarray)RETURNS SETOF anyelement AS $$SELECT $1[idxi]

FROM generate_subscripts($11) AS idx(i)$$ LANGUAGE sql IMMUTABLE

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 107 115

PoleOperace sestavenı pole a rozsirovanı pole

postgres= SELECT ARRAY(SELECT

FROM (VALUES(Pavel)(Tomas)) a) as output

output-----------------PavelTomas(1 row)

postgres= SELECT ARRAY[abc] || text dcolumn-----------abcd(1 row)

postgres= SELECT ARRAY[abc] || ARRAY[de]column

-------------abcde(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 108 115

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 55: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

PoleTransformace pole na relaci a relaci na pole

postgres= SELECT array_agg(x) FROM (VALUES(10)(20)(30)) g(x)array_agg------------102030(1 row)

postgres= SELECT unnest(ARRAY[102030])unnest--------

102030

(3 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 109 115

PoleOperace vyhledavanı I

Seznam operatorugt obsahujelt je obsazenoampamp prunik

= rovnostltgt nerovnost

postgres=CREATE OR REPLACE FUNCTION ra()RETURNS int[] AS $$SELECT ARRAY

(SELECT round(random()10)intFROM generate_series(1 round(random()10)int)

)int[]$$$ LANGUAGE sql VOLATILECREATE FUNCTION

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 110 115

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 56: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

PoleOperace vyhledavanı II

postgres= CREATE TABLE Omega(a int[])postgres= CREATE INDEX idx_omega_a ON Omega USING GIN (a)

postgres= INSERT INTO Omegapostgres- SELECT ra() FROM generate_series(1100000)INSERT 0 100000

postgres= timingTiming is onpostgres= SELECT

FROM omegaWHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 85386 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 111 115

PoleOperace vyhledavanı III

Modul intarray GiST indexsestavenı indexu je nekolikanasobne pomalejsı nez GiN indexupri hledanı pole o malem poctu pomalejsı nez GiN indexs vetsım poctem vyhledavanych prvku (mensı vysledna mnozina) rosterychlost (GiN se chova opacne)

postgres= CREATE INDEX idx_omega_a_gistON Omega USING GIST(a gist__int_ops)

postgres= SELECT FROM Omega WHERE a gt array[12345678910]

a------------------------6423810175996317285104(2 rows)

Time 36071 ms

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 112 115

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 57: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Funkce generate seriesCyklus v SQL

Popisgeneruje jednosloupcovou tabulku s cıselnou posloupnostıumoznuje snadne generovanı testovacıch dat a benchmarkuumoznuje realizovat funkci FOR v cistem SQL

FUNCTION generate_series(integer integer [ integer])RETURNS SETOF integer

postgres= SELECT idxiFROM generate_series(12) AS idx(i)

i---12(2 rows)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 113 115

Funkce generate seriesPrıklad

PopisFunkce rvrs provede prohozenı poradı znaku v retezci

postgres= CREATE OR REPLACE FUNCTION rvrs(varchar)postgres- RETURNS varchar AS $$postgres$$ SELECT array_to_string(ARRAYpostgres$ (SELECT substring($1 si 1)postgres$ FROM generate_series(length($1)1-1) AS s(i)postgres$ ) )postgres$ $$ LANGUAGE SQLCREATE FUNCTIONpostgres= SELECT rvrs(abcde)rvrs-------edcba(1 row)

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 114 115

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series
Page 58: Skolen ˇ ´ı PostgreSQL efektivn eˇ · Skolenˇ ´ı PostgreSQL efektivn eˇ ... vyvoj z´ akaznick´ ych modul´ u do PostgreSQL - v˚ ´ıce na ... MySQL nebo SQLite

Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady

Pavel Stehule

httpwwwpostgrescz

14 7 2015

Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115

  • Podpora PostgreSQL na internetu
  • Instalace ve zkratce
  • Porovnaacuteniacute os SQL RDBMS Firebird PostgreSQL MySQL a SQLite
  • Minimaacutelniacute pozadavky na databaacutezi ACID kriteacuteria
  • Charakteristickeacute prvky PostgreSQL MGA TOAST a WAL
    • Nutneacute zlo priacutekaz VACUUM
      • Uacutedrzba databaacuteze
      • Rozširitelnost
        • Zaacutekladniacute priacutekazy pro spraacutevu PostgreSQL
        • Export import dat
        • Zaacutelohovaacuteniacute obnova databaacuteze
        • Spraacuteva uzivatelu
        • Konfigurace databaacuteze
        • Monitorovaacuteniacute databaacuteze
        • Instalace doplnku
        • Postup pri prechodu na novou verzi
        • Efektivniacute SQL
        • Pouziacutevaacuteniacute indexu
        • Optimalizace dotazu
        • Sekvence
        • Vyhledaacutevaacuteniacute na zaacuteklade podobnosti
        • Pole
        • Funkce generate_series