Upload
truongcong
View
223
Download
1
Embed Size (px)
Citation preview
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Skolenı PostgreSQL efektivneVseobecna cast + administrace - podklady
Pavel Stehule
httpwwwpostgrescz
14 7 2015
Pavel Stehule (httpwwwpostgrescz) Skolenı PostgreSQL efektivne 14 7 2015 115 115