ืฉื™ืžื•ืฉ ื‘ื›ืœ ื”ืชื›ื•ื ื•ืช ืฉืœ ืื™ื ื“ืงืกื™ื ื‘-PostgreSQL

ืฉื™ืžื•ืฉ ื‘ื›ืœ ื”ืชื›ื•ื ื•ืช ืฉืœ ืื™ื ื“ืงืกื™ื ื‘-PostgreSQL
ื‘ืขื•ืœื Postgres, ืื™ื ื“ืงืกื™ื ื—ื™ื•ื ื™ื™ื ืœื ื™ื•ื•ื˜ ื™ืขื™ืœ ื‘ืื—ืกื•ืŸ ืฉืœ ืžืกื“ ื ืชื•ื ื™ื (ื”ืžื›ื•ื ื” "ืขืจื™ืžื”"). Postgres ืœื ืชื•ืžืš ื‘ืืฉื›ื•ืœื•ืช ืขื‘ื•ืจื•, ื•ืืจื›ื™ื˜ืงื˜ื•ืจืช MVCC ื’ื•ืจืžืช ืœืš ืœืงื‘ืœ ื’ืจืกืื•ืช ืจื‘ื•ืช ืฉืœ ืื•ืชื• tuple. ืœื›ืŸ, ื—ืฉื•ื‘ ืžืื•ื“ ืœื”ื™ื•ืช ืžืกื•ื’ืœ ืœื™ืฆื•ืจ ื•ืœืชื—ื–ืง ืื™ื ื“ืงืกื™ื ื™ืขื™ืœื™ื ืœืชืžื™ื›ื” ื‘ืืคืœื™ืงืฆื™ื•ืช.

ืœื”ืœืŸ ืžืกืคืจ ื˜ื™ืคื™ื ืœื™ื™ืขื•ืœ ื•ืฉื™ืคื•ืจ ื”ืฉื™ืžื•ืฉ ื‘ืื™ื ื“ืงืกื™ื.

ื”ืขืจื”: ื”ืฉืื™ืœืชื•ืช ื”ืžื•ืฆื’ื•ืช ืœื”ืœืŸ ืคื•ืขืœื•ืช ืขืœ ืงื•ื‘ืฅ ืœืœื ืฉื™ื ื•ื™ ืžืกื“ ื ืชื•ื ื™ื ืœื“ื•ื’ืžื” ืฉืœ pagila.

ืฉื™ืžื•ืฉ ื‘ืื™ื ื“ืงืกื™ื ืžื›ืกื™ื

ื”ื‘ื” ื ื‘ื—ืŸ ื‘ืงืฉื” ืœื—ื™ืœื•ืฅ ื›ืชื•ื‘ื•ืช ื“ื•ื"ืœ ืขื‘ื•ืจ ืžืฉืชืžืฉื™ื ืœื ืคืขื™ืœื™ื. ืฉื•ืœื—ืŸ customer ื™ืฉ ืขืžื•ื“ื” active, ื•ื”ืฉืื™ืœืชื” ืคืฉื•ื˜ื”:

pagila=# EXPLAIN SELECT email FROM customer WHERE active=0;
                        QUERY PLAN
-----------------------------------------------------------
 Seq Scan on customer  (cost=0.00..16.49 rows=15 width=32)
   Filter: (active = 0)
(2 rows)

ื”ืฉืื™ืœืชื” ืžืคืขื™ืœื” ืืช ืจืฆืฃ ืกืจื™ืงืช ื”ื˜ื‘ืœื” ื”ืžืœื customer. ื‘ื•ืื• ื ื™ืฆื•ืจ ืื™ื ื“ืงืก ืขืœ ืขืžื•ื“ื” active:

pagila=# CREATE INDEX idx_cust1 ON customer(active);
CREATE INDEX
pagila=# EXPLAIN SELECT email FROM customer WHERE active=0;
                                 QUERY PLAN
-----------------------------------------------------------------------------
 Index Scan using idx_cust1 on customer  (cost=0.28..12.29 rows=15 width=32)
   Index Cond: (active = 0)
(2 rows)

ื–ื” ืขื–ืจ, ื”ืกืจื™ืงื” ืฉืœืื—ืจ ืžื›ืŸ ื”ืคื›ื” ืœ"index scan". ื–ื” ืื•ืžืจ ืฉืคื•ืกื˜ื’ืจืก ื™ืกืจื•ืง ืืช ื”ืื™ื ื“ืงืก "idx_cust1", ื•ืœืื—ืจ ืžื›ืŸ ื”ืžืฉืš ืœื—ืคืฉ ื‘ืขืจื™ืžืช ื”ื˜ื‘ืœื” ื›ื“ื™ ืœืงืจื•ื ืืช ื”ืขืจื›ื™ื ืฉืœ ืขืžื•ื“ื•ืช ืื—ืจื•ืช (ื‘ืžืงืจื” ื–ื”, ื”ืขืžื•ื“ื” email) ืฉื”ืฉืื™ืœืชื” ืฆืจื™ื›ื”.

ืื™ื ื“ืงืกื™ื ืžื›ืกื™ื ืžื•ืฆื’ื™ื ื‘-PostgreSQL 11. ื”ื ืžืืคืฉืจื™ื ืœืš ืœื›ืœื•ืœ ืขืžื•ื“ื” ื ื•ืกืคืช ืื—ืช ืื• ื™ื•ืชืจ ื‘ืื™ื ื“ืงืก ืขืฆืžื• - ื”ืขืจื›ื™ื ืฉืœื”ืŸ ืžืื•ื—ืกื ื™ื ื‘ืžืื’ืจ ื ืชื•ื ื™ ื”ืื™ื ื“ืงืก.

ืื ื ื™ืฆืœื ื• ืืช ื”ืชื›ื•ื ื” ื”ื–ื• ื•ื”ื•ืกืคื ื• ืืช ืขืจืš ื”ืื™ืžื™ื™ืœ ื‘ืชื•ืš ื”ืื™ื ื“ืงืก, ืื– Postgres ืœื ื”ื™ื” ืฆืจื™ืš ืœื—ืคืฉ ืืช ื”ืขืจืš ื‘ืขืจื™ืžืช ื”ื˜ื‘ืœื”. email. ื‘ื•ื ื ืจืื” ืื โ€‹โ€‹ื–ื” ื™ืขื‘ื•ื“:

pagila=# CREATE INDEX idx_cust2 ON customer(active) INCLUDE (email);
CREATE INDEX
pagila=# EXPLAIN SELECT email FROM customer WHERE active=0;
                                    QUERY PLAN
----------------------------------------------------------------------------------
 Index Only Scan using idx_cust2 on customer  (cost=0.28..12.29 rows=15 width=32)
   Index Cond: (active = 0)
(2 rows)

ยซIndex Only Scan' ืื•ืžืจ ืœื ื• ืฉื”ืฉืื™ืœืชื” ื–ืงื•ืงื” ื›ืขืช ืจืง ืœืื™ื ื“ืงืก, ืžื” ืฉืขื•ื–ืจ ืœื”ื™ืžื ืข ืžื›ืœ ืงืœื˜/ืคืœื˜ ื“ื™ืกืง ื›ื“ื™ ืœืงืจื•ื ืืช ืขืจื™ืžืช ื”ื˜ื‘ืœื”.

ืื™ื ื“ืงืกื™ื ืžื›ืกื™ื ื–ืžื™ื ื™ื ื›ืจื’ืข ืจืง ืขื‘ื•ืจ ืขืฆื™ B. ืขื ื–ืืช, ื‘ืžืงืจื” ื–ื”, ืžืืžืฅ ื”ืชื—ื–ื•ืงื” ื™ื”ื™ื” ื’ื‘ื•ื” ื™ื•ืชืจ.

ืฉื™ืžื•ืฉ ื‘ืื™ื ื“ืงืกื™ื ื—ืœืงื™ื™ื

ืื™ื ื“ืงืก ื—ืœืงื™ ืžื•ืกื™ืฃ ืจืง ืชืช-ืงื‘ื•ืฆื” ืฉืœ ื”ืฉื•ืจื•ืช ื‘ื˜ื‘ืœื”. ื–ื” ื—ื•ืกืš ืืช ื’ื•ื“ืœ ื”ืื™ื ื“ืงืกื™ื ื•ื”ื•ืคืš ืืช ื”ืกืจื™ืงื” ืœืžื”ื™ืจ ื™ื•ืชืจ.

ื ื ื™ื— ืฉืื ื• ืจื•ืฆื™ื ืœืงื‘ืœ ืจืฉื™ืžื” ืฉืœ ื›ืชื•ื‘ื•ืช ื”ืื™ืžื™ื™ืœ ืฉืœ ื”ืœืงื•ื—ื•ืช ืฉืœื ื• ื‘ืงืœื™ืคื•ืจื ื™ื”. ื”ื‘ืงืฉื” ืชื”ื™ื” ื›ืš:

SELECT c.email FROM customer c
JOIN address a ON c.address_id = a.address_id
WHERE a.district = 'California';
which has a query plan that involves scanning both the tables that are joined:
pagila=# EXPLAIN SELECT c.email FROM customer c
pagila-# JOIN address a ON c.address_id = a.address_id
pagila-# WHERE a.district = 'California';
                              QUERY PLAN
----------------------------------------------------------------------
 Hash Join  (cost=15.65..32.22 rows=9 width=32)
   Hash Cond: (c.address_id = a.address_id)
   ->  Seq Scan on customer c  (cost=0.00..14.99 rows=599 width=34)
   ->  Hash  (cost=15.54..15.54 rows=9 width=4)
         ->  Seq Scan on address a  (cost=0.00..15.54 rows=9 width=4)
               Filter: (district = 'California'::text)
(6 rows)

ืžื” ื™ืชื ื• ืœื ื• ืื™ื ื“ืงืกื™ื ืจื’ื™ืœื™ื:

pagila=# CREATE INDEX idx_address1 ON address(district);
CREATE INDEX
pagila=# EXPLAIN SELECT c.email FROM customer c
pagila-# JOIN address a ON c.address_id = a.address_id
pagila-# WHERE a.district = 'California';
                                      QUERY PLAN
---------------------------------------------------------------------------------------
 Hash Join  (cost=12.98..29.55 rows=9 width=32)
   Hash Cond: (c.address_id = a.address_id)
   ->  Seq Scan on customer c  (cost=0.00..14.99 rows=599 width=34)
   ->  Hash  (cost=12.87..12.87 rows=9 width=4)
         ->  Bitmap Heap Scan on address a  (cost=4.34..12.87 rows=9 width=4)
               Recheck Cond: (district = 'California'::text)
               ->  Bitmap Index Scan on idx_address1  (cost=0.00..4.34 rows=9 width=0)
                     Index Cond: (district = 'California'::text)
(8 rows)

ืกืจื•ืง address ื”ื•ื—ืœืฃ ื‘ืกืจื™ืงืช ืื™ื ื“ืงืก idx_address1ื•ืื– ืกืจืง ืืช ื”ืขืจื™ืžื” address.

ืžื›ื™ื•ื•ืŸ ืฉืžื“ื•ื‘ืจ ื‘ืฉืื™ืœืชื” ืชื›ื•ืคื” ื•ืฆืจื™ืš ืœื‘ืฆืข ืื•ืคื˜ื™ืžื™ื–ืฆื™ื”, ื ื•ื›ืœ ืœื”ืฉืชืžืฉ ื‘ืื™ื ื“ืงืก ื—ืœืงื™, ืฉืžืื ื“ืงืก ืจืง ืืช ื”ืฉื•ืจื•ืช ืขื ื”ื›ืชื•ื‘ื•ืช ืฉื‘ื”ืŸ ื”ืžื—ื•ื– โ€˜Californiaโ€™:

pagila=# CREATE INDEX idx_address2 ON address(address_id) WHERE district='California';
CREATE INDEX
pagila=# EXPLAIN SELECT c.email FROM customer c
pagila-# JOIN address a ON c.address_id = a.address_id
pagila-# WHERE a.district = 'California';
                                           QUERY PLAN
------------------------------------------------------------------------------------------------
 Hash Join  (cost=12.38..28.96 rows=9 width=32)
   Hash Cond: (c.address_id = a.address_id)
   ->  Seq Scan on customer c  (cost=0.00..14.99 rows=599 width=34)
   ->  Hash  (cost=12.27..12.27 rows=9 width=4)
         ->  Index Only Scan using idx_address2 on address a  (cost=0.14..12.27 rows=9 width=4)
(5 rows)

ื›ืขืช ื”ืฉืื™ืœืชื” ืจืง ืงื•ืจืืช idx_address2 ื•ืื™ื ื• ื ื•ื’ืข ื‘ืฉื•ืœื—ืŸ address.

ืฉื™ืžื•ืฉ ื‘ืื™ื ื“ืงืกื™ื ืžืจื•ื‘ื™ ืขืจื›ื™ื

ื™ื™ืชื›ืŸ ืฉื—ืœืง ืžื”ืขืžื•ื“ื•ืช ืœื”ื•ืกืคืช ืื™ื ื“ืงืก ืื™ื ืŸ ืžื›ื™ืœื•ืช ืกื•ื’ ื ืชื•ื ื™ื ืกืงืœืืจื™. ืกื•ื’ื™ ืขืžื•ื“ื•ืช ื›ืžื• jsonb, arrays ะธ tsvector ืžื›ื™ืœื™ื ืขืจื›ื™ื ืžื•ืจื›ื‘ื™ื ืื• ืžืจื•ื‘ื™ื. ืื ืืชื” ืฆืจื™ืš ืœืื™ื ื“ืงืก ืขืžื•ื“ื•ืช ื›ืืœื”, ืืชื” ื‘ื“ืจืš ื›ืœืœ ืฆืจื™ืš ืœื—ืคืฉ ื‘ื›ืœ ื”ืขืจื›ื™ื ื”ื‘ื•ื“ื“ื™ื ื‘ืื•ืชืŸ ืขืžื•ื“ื•ืช.

ื‘ื•ืื• ื ื ืกื” ืœืžืฆื•ื ืืช ื”ื›ื•ืชืจื•ืช ืฉืœ ื›ืœ ื”ืกืจื˜ื™ื ื”ืžื›ื™ืœื™ื ื’ื–ืจื•ืช ืžืฆื™ืœื•ืžื™ื ืœื ืžื•ืฆืœื—ื™ื. ืฉื•ืœื—ืŸ film ื™ืฉ ืขืžื•ื“ืช ื˜ืงืกื˜ ืฉื ืงืจืืช special_features. ืื ืœืกืจื˜ ื™ืฉ "ืžืืคื™ื™ืŸ ืžื™ื•ื—ื“", ืื– ื”ืขืžื•ื“ื” ืžื›ื™ืœื” ืืช ื”ืืœืžื ื˜ ื›ืžืขืจืš ื˜ืงืกื˜ Behind The Scenes. ื›ื“ื™ ืœื—ืคืฉ ืืช ื›ืœ ื”ืกืจื˜ื™ื ื”ืืœื”, ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื‘ื—ื•ืจ ืืช ื›ืœ ื”ืฉื•ืจื•ืช ืขื "ืžืื—ื•ืจื™ ื”ืงืœืขื™ื" ืžืชื™ ื›ืœ ืขืจื›ื™ ืžืขืจืš special_features:

SELECT title FROM film WHERE special_features @> '{"Behind The Scenes"}';

ืžืคืขื™ืœ ืงื™ื ื•ืŸ @> ื‘ื•ื“ืง ืื ื”ืฆื“ ื”ื™ืžื ื™ ื”ื•ื ืชืช-ืงื‘ื•ืฆื” ืฉืœ ื”ืฆื“ ื”ืฉืžืืœื™.

ื‘ืงืฉืช ืชื•ื›ื ื™ืช:

pagila=# EXPLAIN SELECT title FROM film
pagila-# WHERE special_features @> '{"Behind The Scenes"}';
                           QUERY PLAN
-----------------------------------------------------------------
 Seq Scan on film  (cost=0.00..67.50 rows=5 width=15)
   Filter: (special_features @> '{"Behind The Scenes"}'::text[])
(2 rows)

ืžื” ืฉืžื‘ืงืฉ ืกืจื™ืงืช ืขืจื™ืžื” ืžืœืื” ื‘ืขืœื•ืช ืฉืœ 67.

ื‘ื•ื ื ืจืื” ืื โ€‹โ€‹ืื™ื ื“ืงืก ืขืฅ B ืจื’ื™ืœ ืขื•ื–ืจ ืœื ื•:

pagila=# CREATE INDEX idx_film1 ON film(special_features);
CREATE INDEX
pagila=# EXPLAIN SELECT title FROM film
pagila-# WHERE special_features @> '{"Behind The Scenes"}';
                           QUERY PLAN
-----------------------------------------------------------------
 Seq Scan on film  (cost=0.00..67.50 rows=5 width=15)
   Filter: (special_features @> '{"Behind The Scenes"}'::text[])
(2 rows)

ื”ืžื“ื“ ืืคื™ืœื• ืœื ื ื—ืฉื‘. ืื™ื ื“ืงืก ืขืฅ B ืื™ื ื• ืžื•ื“ืข ืœืงื™ื•ืžื ืฉืœ ืืœืžื ื˜ื™ื ื‘ื•ื“ื“ื™ื ื‘ืขืจื›ื™ื ื”ืžืฆื•ืจืคื™ื.

ืื ื—ื ื• ืฆืจื™ื›ื™ื ืžื“ื“ GIN.

pagila=# CREATE INDEX idx_film2 ON film USING GIN(special_features);
CREATE INDEX
pagila=# EXPLAIN SELECT title FROM film
pagila-# WHERE special_features @> '{"Behind The Scenes"}';
                                QUERY PLAN
---------------------------------------------------------------------------
 Bitmap Heap Scan on film  (cost=8.04..23.58 rows=5 width=15)
   Recheck Cond: (special_features @> '{"Behind The Scenes"}'::text[])
   ->  Bitmap Index Scan on idx_film2  (cost=0.00..8.04 rows=5 width=0)
         Index Cond: (special_features @> '{"Behind The Scenes"}'::text[])
(4 rows)

ืื™ื ื“ืงืก GIN ืชื•ืžืš ื‘ืžื™ืคื•ื™ ืขืจื›ื™ื ื‘ื•ื“ื“ื™ื ืžื•ืœ ืขืจื›ื™ื ืžืจื•ื›ื‘ื™ื ืฉืฆื•ืจืคื• ืœืื™ื ื“ืงืก, ื•ื›ืชื•ืฆืื” ืžื›ืš ืขืœื•ืช ืชื•ื›ื ื™ืช ืฉืื™ืœืชื•ืช ื”ื™ื ื™ื•ืชืจ ืžื—ืฆื™ื™ืช.

ื”ื™ืคื˜ืจื•ืช ืžืื™ื ื“ืงืกื™ื ื›ืคื•ืœื™ื

ืื™ื ื“ืงืกื™ื ืžืฆื˜ื‘ืจื™ื ืขื ื”ื–ืžืŸ, ื•ืœืคืขืžื™ื ืื™ื ื“ืงืก ื—ื“ืฉ ืขืฉื•ื™ ืœื”ื›ื™ืœ ื”ื’ื“ืจื” ื–ื”ื” ืœืื—ื“ ืžื”ืงื•ื“ืžื™ื. ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืชืฆื•ื’ืช ื”ืงื˜ืœื•ื’ ื›ื“ื™ ืœืงื‘ืœ ื”ื’ื“ืจื•ืช SQL ื”ื ื™ืชื ื•ืช ืœืงืจื™ืื” ืขืœ ื™ื“ื™ ืื“ื ืฉืœ ืื™ื ื“ืงืกื™ื. pg_indexes. ืืชื” ื™ื›ื•ืœ ื’ื ืœืžืฆื•ื ื‘ืงืœื•ืช ื”ื’ื“ืจื•ืช ื–ื”ื•ืช:

 SELECT array_agg(indexname) AS indexes, replace(indexdef, indexname, '') AS defn
    FROM pg_indexes
GROUP BY defn
  HAVING count(*) > 1;
And hereโ€™s the result when run on the stock pagila database:
pagila=#   SELECT array_agg(indexname) AS indexes, replace(indexdef, indexname, '') AS defn
pagila-#     FROM pg_indexes
pagila-# GROUP BY defn
pagila-#   HAVING count(*) > 1;
                                indexes                                 |                                defn
------------------------------------------------------------------------+------------------------------------------------------------------
 {payment_p2017_01_customer_id_idx,idx_fk_payment_p2017_01_customer_id} | CREATE INDEX  ON public.payment_p2017_01 USING btree (customer_id
 {payment_p2017_02_customer_id_idx,idx_fk_payment_p2017_02_customer_id} | CREATE INDEX  ON public.payment_p2017_02 USING btree (customer_id
 {payment_p2017_03_customer_id_idx,idx_fk_payment_p2017_03_customer_id} | CREATE INDEX  ON public.payment_p2017_03 USING btree (customer_id
 {idx_fk_payment_p2017_04_customer_id,payment_p2017_04_customer_id_idx} | CREATE INDEX  ON public.payment_p2017_04 USING btree (customer_id
 {payment_p2017_05_customer_id_idx,idx_fk_payment_p2017_05_customer_id} | CREATE INDEX  ON public.payment_p2017_05 USING btree (customer_id
 {idx_fk_payment_p2017_06_customer_id,payment_p2017_06_customer_id_idx} | CREATE INDEX  ON public.payment_p2017_06 USING btree (customer_id
(6 rows)

ืื™ื ื“ืงืกื™ื ืฉืœ Superset

ื™ื›ื•ืœ ืœืงืจื•ืช ืฉื‘ืกื•ืคื• ืฉืœ ื“ื‘ืจ ืชื’ื™ืขื• ืขื ืื™ื ื“ืงืกื™ื ืจื‘ื™ื, ืฉืื—ื“ ืžื”ื ืื™ื ื“ืงืก ืงื‘ื•ืฆื” ืฉืœ ืขืžื•ื“ื•ืช ืฉืžืื ื“ืงืกื•ืช ืื™ื ื“ืงืกื™ื ืื—ืจื™ื. ื–ื” ืขืฉื•ื™ ืœื”ื™ื•ืช ืจืฆื•ื™ ื•ืื•ืœื™ ืœื - ืขืจื›ืช ื”ืขืœ ืขืฉื•ื™ื” ืœื’ืจื•ื ืœืกืจื™ืงื•ืช ืื™ื ื“ืงืก ื‘ืœื‘ื“, ื•ื–ื” ื˜ื•ื‘, ืื‘ืœ ื”ื™ื ืขืฉื•ื™ื” ืœืชืคื•ืก ื™ื•ืชืจ ืžื“ื™ ืžืงื•ื, ืื• ืฉื”ืฉืื™ืœืชื” ืฉืžืขืจื›ืช ื”ืขืœ ื ื•ืขื“ื” ืœื™ื™ืขืœ ืื™ื ื” ื‘ืฉื™ืžื•ืฉ ืขื•ื“.

ืื ืืชื” ืฆืจื™ืš ืœื”ืคื•ืš ืืช ื”ื”ื’ื“ืจื” ืฉืœ ืื™ื ื“ืงืกื™ื ื›ืืœื” ืœืื•ื˜ื•ืžื˜ื™, ืืชื” ื™ื›ื•ืœ ืœื”ืชื—ื™ืœ ืขื pg_index ืžื”ืฉื•ืœื—ืŸ pg_catalog.

ืื™ื ื“ืงืกื™ื ืฉืื™ื ื ื‘ืฉื™ืžื•ืฉ

ื›ื›ืœ ืฉื™ื™ืฉื•ืžื™ื ื”ืžืฉืชืžืฉื™ื ื‘ืžืกื“ื™ ื ืชื•ื ื™ื ืžืชืคืชื—ื™ื, ื›ืš ื’ื ื”ืฉืื™ืœืชื•ืช ืฉื‘ื”ืŸ ื”ื ืžืฉืชืžืฉื™ื ืžืชืคืชื—ื•ืช. ืœื ื ื™ืชืŸ ืขื•ื“ ืœื”ืฉืชืžืฉ ื‘ืื™ื ื“ืงืกื™ื ืฉื ื•ืกืคื• ืงื•ื“ื ืœื›ืŸ ืขืœ ื™ื“ื™ ืฉืื™ืœืชื” ื›ืœืฉื”ื™. ื‘ื›ืœ ืคืขื ืฉืื™ื ื“ืงืก ื ืกืจืง, ื”ื•ื ืžืกื•ืžืŸ ืขืœ ื™ื“ื™ ืžื ื”ืœ ื”ืกื˜ื˜ื™ืกื˜ื™ืงื”, ื•ื‘ืชืฆื•ื’ืช ืงื˜ืœื•ื’ ื”ืžืขืจื›ืช pg_stat_user_indexes ืืชื” ื™ื›ื•ืœ ืœืจืื•ืช ืืช ื”ืขืจืš idx_scan, ืฉื”ื•ื ืžื•ื ื” ืžืฆื˜ื‘ืจ. ืžืขืงื‘ ืื—ืจ ืขืจืš ื–ื” ืขืœ ืคื ื™ ืชืงื•ืคื” ืฉืœ ื–ืžืŸ (ื ื ื™ื— ื—ื•ื“ืฉ) ื™ื™ืชืŸ ืžื•ืฉื’ ื˜ื•ื‘ ื‘ืื™ืœื• ืื™ื ื“ืงืกื™ื ืื™ื ื ื‘ืฉื™ืžื•ืฉ ื•ื™ื›ื•ืœื™ื ืœื”ื™ืฉืžื˜.

ื”ื ื” ืฉืื™ืœืชื” ืœืงื‘ืœ ืืช ืกืคื™ืจืช ื”ืกืจื™ืงื” ื”ื ื•ื›ื—ื™ืช ืฉืœ ื›ืœ ื”ืื™ื ื“ืงืกื™ื ื‘ืกื›ื™ืžื” โ€˜publicโ€™:

SELECT relname, indexrelname, idx_scan
FROM   pg_catalog.pg_stat_user_indexes
WHERE  schemaname = 'public';
with output like this:
pagila=# SELECT relname, indexrelname, idx_scan
pagila-# FROM   pg_catalog.pg_stat_user_indexes
pagila-# WHERE  schemaname = 'public'
pagila-# LIMIT  10;
    relname    |    indexrelname    | idx_scan
---------------+--------------------+----------
 customer      | customer_pkey      |    32093
 actor         | actor_pkey         |     5462
 address       | address_pkey       |      660
 category      | category_pkey      |     1000
 city          | city_pkey          |      609
 country       | country_pkey       |      604
 film_actor    | film_actor_pkey    |        0
 film_category | film_category_pkey |        0
 film          | film_pkey          |    11043
 inventory     | inventory_pkey     |    16048
(10 rows)

ื‘ื ื™ื™ื” ืžื—ื“ืฉ ืฉืœ ืื™ื ื“ืงืกื™ื ืขื ืคื—ื•ืช ืžื ืขื•ืœื™ื

ืœืขืชื™ื ืงืจื•ื‘ื•ืช ืฆืจื™ืš ืœื‘ื ื•ืช ืžื—ื“ืฉ ืื™ื ื“ืงืกื™ื, ืœืžืฉืœ ื›ืฉื”ื ืžืชื ืคื—ื™ื, ื•ื‘ื ื™ื™ื” ืžื—ื“ืฉ ื™ื›ื•ืœื” ืœื”ืื™ืฅ ืืช ื”ืกืจื™ืงื”. ื’ื ืื™ื ื“ืงืกื™ื ืขืœื•ืœื™ื ืœื”ื™ืคื’ื. ืฉื™ื ื•ื™ ืคืจืžื˜ืจื™ ื”ืื™ื ื“ืงืก ืขืฉื•ื™ ืœื“ืจื•ืฉ ื’ื ื‘ื ื™ื™ื” ืžื—ื“ืฉ ืฉืœื•.

ืืคืฉืจ ื™ืฆื™ืจืช ืื™ื ื“ืงืก ืžืงื‘ื™ืœ

ื‘-PostgreSQL 11, ื™ืฆื™ืจืช ืื™ื ื“ืงืก B-Tree ืžืชื‘ืฆืขืช ื‘ืžืงื‘ื™ืœ. ื›ื“ื™ ืœื”ืื™ืฅ ืืช ืชื”ืœื™ืš ื”ื™ืฆื™ืจื”, ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ืžืกืคืจ ืขื•ื‘ื“ื™ื ืžืงื‘ื™ืœื™ื. ืขื ื–ืืช, ื•ื“ื ืฉืืคืฉืจื•ื™ื•ืช ื”ืชืฆื•ืจื” ื”ืœืœื• ืžื•ื’ื“ืจื•ืช ื›ื”ืœื›ื”:

SET max_parallel_workers = 32;
SET max_parallel_maintenance_workers = 16;

ืขืจื›ื™ ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ืงื˜ื ื™ื ืžื“ื™. ื‘ืื•ืคืŸ ืื™ื“ื™ืืœื™, ืžืกืคืจื™ื ืืœื” ืฆืจื™ื›ื™ื ืœื’ื“ื•ืœ ื™ื—ื“ ืขื ืžืกืคืจ ืœื™ื‘ื•ืช ื”ืžืขื‘ื“. ืงืจื ืขื•ื“ ื‘ ืชื™ืขื•ื“.

ื™ืฆื™ืจืช ืื™ื ื“ืงืก ืจืงืข

ื ื™ืชืŸ ืœื™ืฆื•ืจ ืื™ื ื“ืงืก ื‘ืจืงืข ื‘ืืžืฆืขื•ืช ื”ืืคืฉืจื•ืช CONCURRENTLY ืฆื•ื•ืชื™ื CREATE INDEX:

pagila=# CREATE INDEX CONCURRENTLY idx_address1 ON address(district);
CREATE INDEX

ื”ืœื™ืš ื™ืฆื™ืจืช ืื™ื ื“ืงืก ื–ื” ืฉื•ื ื” ืžื”ืจื’ื™ืœ ื‘ื›ืš ืฉื”ื•ื ืื™ื ื• ืžืฆืจื™ืš ื ืขื™ืœื” ืขืœ ื”ืฉื•ืœื—ืŸ, ื•ืœื›ืŸ ืื™ื ื• ื—ื•ืกื ืคืขื•ืœื•ืช ื›ืชื™ื‘ื”. ืžืฆื“ ืฉื ื™, ื–ื” ืœื•ืงื— ื™ื•ืชืจ ื–ืžืŸ ื•ืฆื•ืจืš ื™ื•ืชืจ ืžืฉืื‘ื™ื.

Postgres ืžืกืคืงืช ื’ืžื™ืฉื•ืช ืจื‘ื” ืœื™ืฆื™ืจืช ืื™ื ื“ืงืกื™ื ื•ื“ืจื›ื™ื ืœืคืชื•ืจ ื›ืœ ืžืงืจื™ื ืžื™ื•ื—ื“ื™ื, ื›ืžื• ื’ื ื“ืจื›ื™ื ืœื ื”ืœ ืืช ืžืกื“ ื”ื ืชื•ื ื™ื ืœืžืงืจื” ืฉื”ืืคืœื™ืงืฆื™ื” ืฉืœืš ืชื’ื“ืœ ื‘ืฆื•ืจื” ืžืคื•ืฆืฆืช. ืื ื• ืžืงื•ื•ื™ื ืฉื”ื˜ื™ืคื™ื ื”ืœืœื• ื™ืขื–ืจื• ืœืš ืœืงื‘ืœ ืืช ื”ืฉืื™ืœืชื•ืช ืฉืœืš ื‘ืžื”ื™ืจื•ืช ื•ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื ืฉืœืš ืžื•ื›ืŸ ืœื”ืจื—ื‘ื”.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”