sql >> Databáze >  >> RDS >> PostgreSQL

Optimalizace dotazů v PostgreSQL. Základy VYSVĚTLENÍ – 3. část

Pokračuji v sérii článků o základech EXPLAIN v PostgreSQL, což je krátká recenze Understanding EXPLAIN od Guillaume Lelarge.
Abyste problému lépe porozuměli, vřele doporučuji prostudovat si původní „Understanding EXPLAIN“ od Guillaume Lelarge a přečtěte si můj první a druhý článek.

OBJEDNAT PODLE

DROP INDEX foo_c1_idx;
EXPLAIN (ANALYZE) SELECT * FROM foo ORDER BY c1;

Nejprve provedete sekvenční skenování (Seq Scan) tabulky foo a poté provedete třídění (Sort). Znak -> příkazu EXPLAIN označuje hierarchii kroků (uzel). Čím dříve je krok proveden, tím větší odsazení má.

Klíč řazení je podmínkou řazení.

Způsob řazení:externí sloučení Disk Při třídění se použije dočasný soubor na disku o kapacitě 4592 kB.
Zaškrtněte u možnosti VYROVNÁVACÍ PAMĚTI:

DROP INDEX foo_c1_idx;
EXPLAIN (ANALYZE) SELECT * FROM foo ORDER BY c1;

temp read=5745 write=5745 line skutečně znamená, že 45960Kb (5745 bloků po 8Kb každý) bylo uloženo a přečteno v dočasném souboru. Operace s 8334 bloky byly provedeny v mezipaměti.

Operace se souborovým systémem jsou pomalejší než operace v RAM.

Zkusme zvýšit kapacitu paměti work_mem:

SET work_mem TO '200MB';
EXPLAIN (ANALYZE) SELECT * FROM foo ORDER BY c1;

Způsob řazení:quicksort Paměť:102702 kB – celé řazení bylo provedeno v RAM.
Index je následující:

CREATE INDEX ON foo(c1);
EXPLAIN (ANALYZE) SELECT * FROM foo ORDER BY c1;

Zůstal nám pouze Index Scan, který výrazně ovlivnil rychlost dotazu.

LIMIT

Odstraňte dříve vytvořený index:

DROP INDEX foo_c2_idx1;
EXPLAIN (ANALYZE,BUFFERS)
  SELECT * FROM foo WHERE c2 LIKE 'ab%';

Podle očekávání jsou použity Seq Scan a Filter.

EXPLAIN (ANALYZE,BUFFERS)
SELECT * FROM foo WHERE c2 LIKE 'ab%' LIMIT 10;

Seq Scan čte řádky tabulky a porovnává je (Filtr) s podmínkou. Jakmile bude 10 záznamů splňovat podmínku, skenování se ukončí. V našem případě, abychom získali 10 výsledkových řádků, museli jsme číst pouze 3063 záznamů, nikoli celou tabulku. 3053 řádků z tohoto čísla bylo odmítnuto (řádky odstraněny filtrem).
Totéž se děje s indexovým skenováním.

PŘIPOJIT SE

Vytvořte novou tabulku a vygenerujte pro ni statistiky:

CREATE TABLE bar (c1 integer, c2 boolean);
INSERT INTO bar
  SELECT i, i%2=1
  FROM generate_series(1, 500000) AS i;
ANALYZE bar;

Dotaz na dvě tabulky je následující:

EXPLAIN (ANALYZE)
SELECT * FROM foo JOIN bar ON foo.c1=bar.c1;

Nejprve sekvenční skenování (Seq Scan) přečte tabulku sloupců. Pro každý řádek se vypočítá hash (Hash).

Poté prohledá tabulku foo a pro každý řádek se vypočítá hash, který se porovná (Hash Join) s hashem tabulky sloupců pomocí podmínky Hash Cond. Pokud se shodují, vypíše se výsledný řetězec.

18067 kB paměti se používá k ukládání hashů pro lištu.

Přidejte index:

CREATE INDEX ON bar(c1);
EXPLAIN (ANALYZE)
SELECT * FROM foo JOIN bar ON foo.c1=bar.c1;

Hash se již nepoužívá. Sloučení spojení a skenování indexů na indexech obou tabulek výrazně zvyšují výkon.

LEVÉ PŘIPOJENÍ:

EXPLAIN (ANALYZE)
SELECT * FROM foo LEFT JOIN bar ON foo.c1=bar.c1;

Seq Scan?

Podívejme se, jaký výsledek budeme mít, pokud deaktivujeme Seq Scan.

SET enable_seqscan TO off; 
EXPLAIN (ANALYZE)
SELECT * FROM foo LEFT JOIN bar ON foo.c1=bar.c1;

Podle plánovače je použití indexů nákladnější než použití hashů. To je možné s dostatečně velkým množstvím alokované paměti. Pamatujete si, že jsme zvýšili work_mem?

Pokud však nemáte dostatek paměti, plánovač se bude chovat jinak:

SET work_mem TO '15MB';
SET enable_seqscan TO ON; 
EXPLAIN (ANALYZE)
SELECT * FROM foo LEFT JOIN bar ON foo.c1=bar.c1;

Pokud zakážeme Index Scan, jaký výsledek EXPLAIN zobrazí?

SET work_mem TO '15MB';
SET enable_indexscan TO off; 
EXPLAIN (ANALYZE)
SELECT * FROM foo LEFT JOIN bar ON foo.c1=bar.c1;

Dávky:2 má zvýšené náklady. Celý hash se nevešel do paměti; museli jsme to rozdělit do dvou balíčků po 9045 kB.

Děkuji, že čtete mé články! Doufám, že byly užitečné. Pokud máte nějaké připomínky nebo zpětnou vazbu, neváhejte mi dát vědět.


  1. 4 způsoby, jak databáze zásob těží z maloobchodu

  2. Unit testování pro PL/SQL

  3. Jak importovat soubor XML v Oracle SQL Developer?

  4. Použití Oracle JDeveloper 12c s databází Oracle, část 1