PostgreSQL 9.4 - Novinky (a JSONB) Tomáš Vondra, GoodData (tomas.vondra@gooddata.com) http://blog.pgaddict.com (tomas@pgaddict.



Podobné dokumenty
Novinky v PostgreSQL 9.4. Tomáš Vondra, 2ndQuadrant

INDEXY JSOU GRUNT. Pavel Stěhule

PG 9.5 novinky ve vývoji aplikací

PostgreSQL. Podpora dědičnosti Rozšiřitelnost vlastní datové typy. Univerzální nasazení ve vědecké sféře

Verzování a publikace dat na webu za pomoci PostgreSQL

Paralelní dotazy v PostgreSQL 9.6 (a 10.0)

Databázové systémy II. KIV/DB2 LS 2007/2008. Zadání semestrální práce

Výkonnostní archeologie

Čteme EXPLAIN. CSPUG, Praha. Tomáš Vondra Czech and Slovak PostgreSQL Users Group

Kurz Databáze. Obsah. Dotazy. Zpracování dat. Doc. Ing. Radim Farana, CSc.

zobrazení délky ve výpisu v psql

Optimalizace dotazů a databázové transakce v Oracle

Tabulka fotbalové ligy

B0M33BDT Technologie pro velká data. Supercvičení SQL, Python, Linux

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

Informační systémy 2008/2009. Radim Farana. Obsah. Jazyk SQL

PL/SQL. Jazyk SQL je jazykem deklarativním, který neobsahuje procedurální příkazy jako jsou cykly, podmínky, procedury, funkce, atd.

Databázové systémy Cvičení 5.2

Databáze I. 5. přednáška. Helena Palovská

SQL injection princip a ochrana

Databáze I. Přednáška 7

Databázové systémy. Cvičení 6: SQL

InnoDB transakce, cizí klíče, neumí fulltext (a nebo už ano?) CSV v textovém souboru ve formátu hodnot oddělených čárkou

2. blok část B Základní syntaxe příkazů SELECT, INSERT, UPDATE, DELETE

Bi-Direction Replication

Stored Procedures & Database Triggers, Tiskové sestavy v Oracle Reports

Ukládání a vyhledávání XML dat

Obchodní akademie a Jazyková škola s právem státní jazykové zkoušky Jihlava

Operátory ROLLUP a CUBE

Návrh a tvorba WWW stránek 1/14. PHP a databáze

Materializované pohledy

MySQL sežere vaše data

Databáze SQL SELECT. David Hoksza

RNDr. Michal Kopecký, Ph.D. Department of Software Engineering, Faculty of Mathematics and Physics, Charles University in Prague

TimescaleDB. Pavel Stěhule 2018

Virtual Private Database (VPD) Jaroslav Kotrč

7. Integrita a bezpečnost dat v DBS

7. Integrita a bezpečnost dat v DBS

XMW4 / IW4 Pokročilé SELECT dotazy. Štefan Pataky

Novinky ve starém dobrém SQL světě OpenAlt, 2014/11/02

Sada 1 - PHP. 14. Úvod do jazyka SQL

KIV/ZIS cvičení 5. Tomáš Potužák

Databázové systémy. Dotazovací jazyk SQL - III

Databáze I. Přednáška 4

Semestrální práce z DAS2 a WWW

Databázové systémy I

Použití PostgreSQL v. P2D Martin Swiech

IDS optimalizátor. Ing. Jan Musil, IBM ČR Community of Practice for

Jazyk SQL databáze SQLite. připravil ing. petr polách

Databázové systémy úvod

Administrace Oracle. Práva a role, audit

Databáze. Velmi stručný a zjednodušený úvod do problematiky databází pro programátory v Pythonu. Bedřich Košata

První pomoc pro DBA. administrátory CIDUG. Milan Rafaj IBM Česká republika

Informační systémy 2008/2009. Radim Farana. Obsah. Dotazy přes více tabulek

Základy informatiky. 08 Databázové systémy. Daniela Szturcová

PL/pgSQL. Pavel

Úvod do databázových systémů

Co bude výsledkem mého SELECTu? RNDr. David Gešvindr MVP: Data Platform MCSE: Data Platform MCSD: Windows Store MCT

SQL - trigger, Databázové modelování

Databázové systémy a SQL

Databázové systémy a SQL

POSTUP PRO VYTVOŘENÍ STRUKTUR PRO UKLÁDÁNÍ RDF DAT V ORACLE

Databáze I. Přednáška 6

SQL. strukturovaný dotazovací jazyk. Structured Query Language (SQL)

Michal Krátký, Miroslav Beneš

SQL injection jak ji možná neznáte Roman Kümmel

Jak ušetřit místo a zároveň mít data snadno dostupná. David Turoň

SQL v14. 4D Developer konference. 4D Developer conference 2015 Prague, CZ Celebrating 30 years

Inovace a zkvalitnění výuky prostřednictvím ICT. Základní seznámení s MySQL Ing. Kotásek Jaroslav

Multi-dimensional expressions

Implementace funkce XMLTABLE v PostgreSQL. Pavel

Virtual private database. Antonín Steinhauser

Vzorové příklady SQL. Tabulka: Kniha CREATE TABLE kniha (id INTEGER, název VARCHAR(50), PRIMARY KEY (id))

4IT218 Databáze. 4IT218 Databáze

Jazyk SQL 3 - DML, DDL, TCL, DCL

Oracle XML DB. Tomáš Nykodým

Databázové systémy I

O Apache Derby detailněji. Hynek Mlnařík

Západočeská univerzita v Plzni Katedra informatiky a výpočetní techniky. 9. června krovacek@students.zcu.cz

Relační DB struktury sloužící k optimalizaci dotazů - indexy, clustery, indexem organizované tabulky

8.2 Používání a tvorba databází

Databázové systémy. Integritní omezení. Vilém Vychodil. V. Vychodil (KMI/DATA1, Přednáška 9) Integritní omezení Databázové systémy 1 / 33

Databázové a informační systémy Jana Šarmanová

Jazyk SQL slajdy k přednášce NDBI001

Základní přehled SQL příkazů

Monitoring výkonu PostgreSQL

Replikace je proces kopírování a udržování databázových objektů, které tvoří distribuovaný databázový systém. Změny aplikované na jednu část jsou

Jazyk PL/SQL Úvod, blok

Vkládání, aktualizace, mazání

SII - Informatika. 1. Atribut relace, jehož hodnota jednoznačně určuje prvek v jiné relaci, se nazývá:

RELAČNÍ DATABÁZOVÉ SYSTÉMY

OBJECT DEFINITION LANGUAGE. Jonáš Klimeš NDBI001 Dotazovací Jazyky I 2013

SSD vs. HDD / WAL, indexy a fsync

Základy informatiky. 06 Databázové systémy. Kačmařík/Szturcová/Děrgel/Rapant

Databázové systémy, MS Access. Autor: Ing. Jan Nožička SOŠ a SOU Česká Lípa VY_32_INOVACE_1130_Databázové systémy, MS Access_PWP

MySQL. mysql> CREATE DATABASE nova CHARACTER SET latin2 COLLATE latin2_czech_cs; Query OK, 1 row affected (0.02 sec)

Osnova je orientační pro FIT, u FEKTu se dá předpokládat, že budou zohledněny předchozí znalosti studentů, kde většina s databází nikdy přímo

Databáze 2011/2012 SQL DDL (CREATE/ALTER/DROP TABLE), DML (INSERT/UPDATE/DELETE) RNDr.David Hoksza, Ph.D.

6. SQL složitější dotazy, QBE

RNDr. Michal Kopecký, Ph.D. Department of Software Engineering, Faculty of Mathematics and Physics, Charles University in Prague

Transkript:

PostgreSQL 9.4 - Novinky (a JSONB) Tomáš Vondra, GoodData (tomas.vondra@gooddata.com) http://blog.pgaddict.com (tomas@pgaddict.com)

9.4 release notes http://www.postgresql.org/docs/9.4/static/release-9-4.html článek od Pavla Stěhule (květen 2015) http://www.root.cz/clanky/postgresql-9-4-transakcni-sql-json-databaze/ What's new in PostgreSQL 9.4 (Magnus Hagander) http://www.hagander.net/talks/postgresql94_2.pdf PostgreSQL Conference Europe 2014 (říjen, Madrid) https://wiki.postgresql.org/wiki/postgresql_conference_europe_talks_2014

Postup vývoje 9.4 2013 červen 9.3 branch 2013 červen commitfest #1 2013 září commitfest #2 2013 listopad commitfest #3 2014 leden commitfest #4 2014 květen beta 1 2014 červenec beta 2 2014 říjen beta 3 2014 listopad (?) PostgreSQL 9.4.0

Aktuální stav testuje se beta3 Pomozte s testováním! Aplikační testy nade vše (zkuste svoji aplikaci na 9.4). trochu statistiky 2222 souborů změněno 131805 nových řádek (+) 59333 smazaných řádek (-) méně než 9.3... ale všichni víme že LOC je výborná metrika ;-)

https://www.openhub.net/p/postgres

Takže co je vlastně nového? vývojářské / SQL vlastnosti DBA a administrace replikace a recovery infrastruktura

Vývojářské / SQL vlastnosti agregační funkce FILTER aggregates ordered-set aggregates další menší vylepšení vylepšení aktualizovatelných pohledů UNNEST (WITH ORDINALITY) pl/pgsql stacktrace JSONB (nejlepší na závěr)

agregační výrazy (FILTER) SELECT a, SUM(CASE WHEN b < 10 THEN c ELSE NULL END) AS pod_10, SUM(CASE WHEN b >= 10 THEN c ELSE NULL END) AS nad_10 FROM tabulka GROUP BY a; SELECT a, SUM(c) FILTER (WHERE b < 10) AS pod_10, SUM(c) FILTER (WHERE b >= 10) AS nad_10 FROM tabulka GROUP BY a;

ordered-set aggregates pořadí vstupních hodnot není definováno často nepodstatné (MIN, MAX, SUM, ) někdy na něm ale záleží (array_agg, string_agg, ) lze ho určit pomocí ORDER BY ve volání funkce SELECT a, SUM(b ORDER BY c) AS suma_b_serazene_dle_c, ARRAY_AGG(b ORDER BY c) AS pole_b_serazene_dle_c FROM tabulka GROUP BY a; ( Toto není ordered-set aggregate! )

ordered-set aggregates některé agregační funkce pořadí vyžadují z definice (jinak to prostě nedává smysl) rank, percentil,... direct / aggregate argumenty (rozdíl) SELECT a, PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY b) AS median_b FROM tabulka GROUP BY a;

ordered-set aggregates některé agregační funkce pořadí vyžadují z definice (jinak to prostě nedává smysl) rank, percentil,... direct / aggregate argumenty (rozdíl) SELECT a, PERCENTILE_DISC(ARRAY[0.25, 0.5, 0.75]) WITHIN GROUP (ORDER BY b) AS median_b FROM tabulka GROUP BY a; ( proprietární rozšíření )

hypotetické agregační funkce Kam by se zařadila daná hodnota? pořadí rank(..), dense_rank(..) relativní (0, 1) percent_rank(..), cume_dist(..) SELECT a, rank('xyz') WITHIN GROUP (ORDER BY b), dense_rank('xyz') WITHIN GROUP (ORDER BY b), percent_rank('xyz') WITHIN GROUP (ORDER BY b) FROM tabulka GROUP BY a;

agregační funkce / další vylepšení group keys v EXPLAIN EXPLAIN SELECT COUNT(a) FROM tabulka GROUP BY b; QUERY PLAN -------------------------------------------------------------- HashAggregate (cost=195.00..195.11 rows=11 width=8) Group Key: b -> Seq Scan on tabulka (cost=0.00..145.00 rows=100 width=8) (3 rows)

automaticky updatovatelné pohledy pro jednoduché pohledy lze překládat DML příkazy jedna tabulka ve FROM bez agregací / množinových operací, apod. pouze jednoduché odkazy na sloupce tabulky nesmí být označený pomocí security_barrier od 9.4 lze používat výrazy, konstanty, volání funkcí samozřejmě tyto sloupce nelze měnit CREATE VIEW zamestnanci_view AS SELECT emp_id, dept_id, (salary*0.6) AS cista_mzda FROM zamestnanci_tabulka WHERE dept_id IN (10, 20);

automaticky updatovatelné pohledy řádky odfiltrované přes WHERE nelze updatovat řádek ale může vypadnout WITH CHECK OPTION tomu zabrání další krok na cestě k Row Level Security (řízení přístupu k řádkům) CREATE VIEW zamestnanci_view AS SELECT id_zamestnance, id_oddeleni, (plat*0.6) AS cista_mzda FROM zamestnanci_tabulka WHERE id_oddeleni IN (10, 20) WITH CHECK OPTION; UPDATE zamestnanci_view SET id_oddeleni = 30;

unnest SELECT unnest(array[1,2,3]) AS a; a --- 1 2 3 (3 rows)

unnest SELECT unnest(array[1,2,3]) AS a, unnest(array[4,5,6]) AS b;

unnest SELECT unnest(array[1,2,3]) AS a, a b ---+--- 1 4 2 5 3 6 (3 rows) unnest(array[4,5,6]) AS b;

unnest SELECT unnest(array[1,2,3]) AS a, unnest(array[4,5]) AS b;

unnest SELECT unnest(array[1,2,3]) AS a, a b ---+--- 1 4 2 5 3 4 1 5 2 4 3 5 (6 rows) unnest(array[4,5]) AS b;

unnest SELECT * FROM unnest(array[1,2,3], ARRAY[4,5]) AS t(a,b); a b ---+--- 1 4 2 5 3 (3 rows)

unnest SELECT * FROM unnest(array[1,2,3], ARRAY[4,5]) WITH ORDINALITY AS t(a,b); a b ordinality ---+---+------------ 1 4 1 2 5 2 3 3 (3 rows)

unnest / ROWS FROM SELECT a, b, ordinality FROM ROWS FROM (unnest(array[1,2,3]), unnest(array[4,5])) WITH ORDINALITY AS t(a,b); SELECT a, b, ordinality FROM ROWS FROM (unnest(array[1,2,3]), generate_series(1,10)) WITH ORDINALITY AS t(a,b);

PL/pgSQL / call stack CREATE OR REPLACE FUNCTION inner_func() RETURNS integer AS $$ DECLARE stack text; BEGIN GET DIAGNOSTICS stack = PG_CONTEXT; RAISE NOTICE E'--- Call Stack ---\n%', stack; RETURN 1; END; $$ LANGUAGE plpgsql; SELECT outer_func(); NOTICE: --- Call Stack --- PL/pgSQL function inner_func() line 4 at GET DIAGNOSTICS PL/pgSQL function outer_func() line 3 at RETURN...

PL/pgSQL / call stack CREATE OR REPLACE FUNCTION inner_func() RETURNS integer AS $$ DECLARE stack text; BEGIN GET DIAGNOSTICS stack = PG_CONTEXT; RAISE NOTICE E'--- Call Stack ---\n%', stack; RETURN 1; EXCEPTION WHEN others THEN GET STACKED DIAGNOSTICS stack = PG_ERROR_CONTEXT; RAISE NOTICE E'--- Exception Call Stack ---\n%', stack; END; $$ LANGUAGE plpgsql; (od 9.2, oboje Pavel Stěhule)

DBA a administrace MATERIALIZED VIEWS přesun objektů mezi tablespacy vylepšení GIN (komprese, fast scan) ALTER SYSTEM / pg_reload_conf nové konfigurační parametry pg_prewarm pg_stat_statements (query ID)

MATERIALIZED VIEWS CREATE MATERIALIZED VIEW my_view AS SELECT ; CREATE UNIQUE INDEX my_index ON my_view ( ); REFRESH MATERIALIED VIEW my_view; REFRESH MATERIALIED VIEW CONCURRENTLY my_view;

SET TABLESPACE... ALTER TABLE ALL IN TABLESPACE tablespace1 OWNED BY uzivatel SET TABLESPACE tablespace2 [NOWAIT]; ALTER INDEX... ALTER VIEW... ALTER MATERIALIZED VIEW (rozdíl oproti Pavlově článku / Magnusově prezentaci)

Vylepšení GIN indexů pro hodnoty složené z částí (pole, slova, ) index se skládá z položek key1 => [rowid1, rowid2, rowid3, ] key2 => [rowid10, rowid20, rowid30, ] v podstatě bitmapové indexy (zvláštně kódované) jde použít na skalární typy (extenze btree_gin) dvě významná vylepšení v 9.4 komprese posting listů (seznam odkazů na řádky) fast scan (dotazy typu častý & vzácný výrazně rychlejší)

ALTER SYSTEM dosud bylo nutné přímo editovat postgresql.conf $ vim /var/lib/pgsql/9.1/data/postgresql.conf nově je možné toho dosáhnout přímo z databáze ALTER SYSTEM SET work_mem = '128MB'; vytvoří se nový soubor s konfigurací (include) postgresql.auto.conf stále nutný explicitní reload / restart :-( SELECT pg_reload_conf();

Konfigurační parametry autovacuum_work_mem odděleno z maintenance_work_mem huge_pages Linuxové systémy s velkým objemem RAM session_preload_libraries načtení sdílených knihoven na rozdíl od local_preload_libraries libovolných wal_log_hints standardně se nelogují ale občas jsou užitečné - replikace, rewind (maintenance_)work_mem / effective_cache_size navýšení default hodnot (4x)

pg_prewarm triviální způsob jak zahřát cache page cache (kernel) i shared buffers (DB) statistiky shared_buffers lze získat přes pg_buffercache pg_prewarm(regclass, mode text default 'buffer', fork text default 'main', first_block int8 default null, last_block int8 default null) RETURNS int8 (možná kombinace s pgfincore)

pg_stat_statements texty dotazů se ukládají do souboru šetří sdílenou paměť odstraňuje limit na délku dotazu doplnění query ID (interní hash dotazu) identifikace dotazu (monitorovací nástroje) nestabilní mezi major verzemi / platformami možnost získat statistiky bez textů dotazů SELECT * FROM pg_stat_statements(false); úspornější fungování monitorovacích nástrojů

Replikace a recovery přesun tablespaces v pg_basebackup CREATE TABLESPACE... LOCATION '...'; jiné rozložení disku, stejná mašina => :-( pg_basebackup -T olddir=newdir time-delayed standby (recovery.conf) recovery_min_apply_delay=3600000 pg_stat_archiver čas/počet archivovaných WAL segmentů (atd.) úspěšné i neúspěšné pokusy

Infrastruktura základ logické replikace zpětná extrakce změn z transakčního logu základy v 9.4, další patche (9.5) alternativa k Slony, londiste,... replikační sloty flexibilní zachovávání WAL segmentů alternativa wal_keep_segments / archive_command alternativa hot_standby_feedback / vacuum_defer_cleanup_age

Infrastruktura background workers uživatelské procesy spravované databází (extensions) dynamická registrace, spouštění, ukončování max_worker_processes... vnímáno jako základ pro Parallel Query

Spousta dalšího... http://www.postgresql.org/docs/9.4/static/release-9-4.html spousta malých změn a vylepšení výkonnostní vylepšení zjednodušení práce atd. atd.

JSONB Dokumentace http://www.postgresql.org/docs/9.4/static/datatype-json.html NoSQL on ACID https://wiki.postgresql.org/images/d/de/nosql_training_-_pgconf.eu.pdf

KV a dokumenty v PostgreSQL HSTORE kolekce key-value pouze řetězce, jedna úroveň (bez vnoření) jednoduchá definice, rychlý, snadná práce PostgreSQL 8.2 (2006) predatuje mnohé NoSQL řešení ideální pro řídké kolekce hodnot spousta sloupců, neznámé sloupce,...

KV a dokumenty v PostgreSQL JSON hierarchický model dokumentů 9.2 samostatný datový typ víceméně jenom validace vstupu, minimum funkcí možnost psát funkce v PL/V8, PL/Perl, 9.3 doplněny operátory / funkce pro manipulaci,... JSONB binární reprezentace JSON (neplést s BSON) rychlejší, širší paleta operátorů, robustnější PostgreSQL 9.4 (namísto vyvíjeného HSTORE2)

JSONB příklad CREATE TABLE json_data (data JSONB); INSERT INTO json_data (data) VALUES ('{"name": "Apple Phone", "type": "phone", "brand": "ACME", "price": 200, "available": true, "warranty_years": 1}');

JSONB příklad CREATE TABLE json_data (data JSONB); INSERT INTO json_data (data) VALUES ('{"full name": "John Joseph Carl Salinger", "names": [ {"type": "firstname", "value": "John"}, {"type": "middlename", "value": "Joseph"}, {"type": "middlename", "value": "Carl"}, {"type": "lastname", "value": "Salinger"} ]}');

funkce a operátory http://www.postgresql.org/docs/9.4/static/functions-json.html extrakce hodnot z JSON dokumentů -> jako JSON dokument #> jako JSON dokument ->> jako text #>> jako text containment a existence @> containment (sub-dokument)? existence klíče? existence (alespoň jeden klíč)?& existence (všechny klíče)

extrakce hodnot (jako JSON) SELECT '{"a" : {"b" : "c"}}'::jsonb -> 'a'; {"b": "c"} SELECT '{"a" : {"b" : "c"}}'::jsonb -> 'a' -> 'b'; "c" SELECT '{"a" : {"b" : "c"}}'::jsonb #> '{a, b}'; SELECT '{"a" : {"b" : "c"}}'::jsonb #> ARRAY['a', 'b']; "c"

containment & existence SELECT '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb; true SELECT '{"a":1, "b":2}'::jsonb @> '{"b":3}'::jsonb; false SELECT '{"a":1, "b":2}'::jsonb? 'a'; true SELECT '{"a":1, "b":2}'::jsonb? ARRAY['a', 'c']; true SELECT '{"a":1, "b":2}'::jsonb?& ARRAY['a', 'c']; false

processing functions to_json json_extract_path array_to_json json_extract_path_text row_to_json json_object_keys json_build_array json_populate_record json_build_object json_populate_recordset json_object json_array_elements json_array_elements_text json_array_length json_typeof json_each json_to_record json_each_text json_to_recordset http://www.postgresql.org/docs/9.4/static/functions-json.html

processing functions to_json jsonb_extract_path array_to_json jsonb_extract_path_text row_to_json jsonb_object_keys json_build_array jsonb_populate_record json_build_object jsonb_populate_recordset json_object jsonb_array_elements jsonb_array_elements_text jsonb_array_length jsonb_typeof jsonb_each jsonb_to_record jsonb_each_text jsonb_to_recordset http://www.postgresql.org/docs/9.4/static/functions-json.html

Mailing list archive CREATE TABLE messages ( id integer PRIMARY KEY, parent_id integer, thread_id integer, list varchar(32) NOT NULL, message_id varchar(200),... sent timestamp, author text, subject text, headers jsonb, body_plain text, subject_tsvector tsvector, body_tsvector tsvector );

JSONB / diskový prostor List of relations Schema Name Size --------+----------------------+--------- public headers_jsonb 1244 MB public headers_jsonb_beta_2 1330 MB public headers_json 1517 MB public headers_text 1517 MB dump 1567 MB

Dotazování SELECT COUNT(*) FROM messages WHERE headers? 'bcc'; SELECT (headers->>'message-id') AS mid FROM messages WHERE headers? 'bcc'; SELECT COUNT(*) FROM messages WHERE headers @> '{"from" : "tv@fuzzy.cz"}'; QUERY PLAN ------------------------------------------------------------------ Aggregate (cost=177501.99..177502.00 rows=1 width=0) -> Seq Scan on messages (cost=0.00..177499.70 rows=917 width=0) Filter: (headers @> '{"from": "tv@fuzzy.cz"}'::jsonb) Planning time: 0.178 ms (4 rows)

Indexování / btree nesmysl indexovat celé JSON dokumenty ale indexy nad výrazy lze použít CREATE INDEX messages_cc_idx ON messages ((headers->>'cc')); SELECT * FROM messages WHERE headers->>'cc' = 'tv@fuzzy.cz'; QUERY PLAN ------------------------------------------------------------------------- Bitmap Heap Scan on messages (cost=200.09..16121.34 rows=4585 width=1529) Recheck Cond: ((headers ->> 'cc'::text) = 'tv@fuzzy.cz'::text) -> Bitmap Index Scan on ttt (cost=0.00..198.94 rows=4585 width=0) Index Cond: ((headers ->> 'cc'::text) = 'tv@fuzzy.cz'::text) Planning time: 1.044 ms (5 rows)

Indexování / GIN CREATE INDEX messages_gin_idx ON messages USING gin(headers); SELECT * FROM messages WHERE headers @> '{"cc" : "tv@fuzzy.cz"}'; QUERY PLAN -------------------------------------------------------------------------- Bitmap Heap Scan on messages (cost=51.11..3518.80 rows=917 width=1529) Recheck Cond: (headers @> '{"cc": "tv@fuzzy.cz"}'::jsonb) -> Bitmap Index Scan on messages_gin_idx (cost=0.00..50.88 rows=917 width=0) Index Cond: (headers @> '{"cc": "tv@fuzzy.cz"}'::jsonb) Planning time: 0.135 ms (5 rows)

Indexování / GIN jsonb_ops výchozí operator class všechny základní operátory @>???& jsonb_path_ops menší, rychlejší indexy pouze @> operátor CREATE INDEX headers_path_idx ON messages USING gin(headers jsonb_path_ops); možnost subdocument indexů CREATE INDEX messages_cc_idx ON messages USING gin((headers->'cc'));

Indexování / GIN List of relations Schema Name Size --------+---------------------------+-------- public messages_btree_idx 64 MB public messages_gin_idx 503 MB public messages_gin_path_idx 270 MB public messages_hash_id_key 67 MB public messages_pkey 36 MB public messages_cc_idx 25 MB (4 rows)

PostgrteSQL NoSQL benchmark https://github.com/enterprisedb/pg_nosql_benchmark http://bit.ly/1rxinmp / http://bit.ly/1t2jg1r (nižší hodnoty jsou lepší)

Fulltext benchmark fulltextové vyhledávání v e-mailovém archivu kombinace slov s různou frekvencí 33k reálných dotazů z postgresql.org SELECT id FROM messages WHERE body_fts @@ ('high & performance')::tsquery ORDER BY ts_rank(body_fts, ('high & performance')::tsquery) DESC LIMIT 100;

Fulltext benchmark / 9.3 vs. 9.4 (GIN fastscan) 9.4 durations, divided by 9.3 durations (e.g. 0.1 means 10x speedup) 9.4 duration (relative to 9.3) 1.8 1.6 1.4 1.2 1 0.8 0.6 0.4 0.2 0 0.1 1 10 100 duration on 9.3 [miliseconds, log scale] 1000