PostgreSQL เชฎเชพเช‚ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“เชจเซ€ เชคเชฎเชพเชฎ เชธเซเชตเชฟเชงเชพเช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡

PostgreSQL เชฎเชพเช‚ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“เชจเซ€ เชคเชฎเชพเชฎ เชธเซเชตเชฟเชงเชพเช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡
เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชธ เชตเชฟเชถเซเชตเชฎเชพเช‚, เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชŸเซ‹เชฐเซ‡เชœ (เชœเซ‡เชจเซ‡ "เชนเซ€เชช" เช•เชนเซ‡เชตเชพเชฏ เช›เซ‡) เชจเชพ เช•เชพเชฐเซเชฏเช•เซเชทเชฎ เชจเซ‡เชตเชฟเช—เซ‡เชถเชจ เชฎเชพเชŸเซ‡ เช‡เชจเซเชกเซ‡เช•เซเชธ เช†เชตเชถเซเชฏเช• เช›เซ‡. เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชธ เชคเซ‡เชจเชพ เชฎเชพเชŸเซ‡ เช•เซเชฒเชธเซเชŸเชฐเชฟเช‚เช—เชจเซ‡ เชธเชชเซ‹เชฐเซเชŸ เช•เชฐเชคเซเช‚ เชจเชฅเซ€, เช…เชจเซ‡ MVCC เช†เชฐเซเช•เชฟเชŸเซ‡เช•เซเชšเชฐ เชคเชฎเชจเซ‡ เชธเชฎเชพเชจ เชŸเซเชฏเซเชชเชฒเชจเชพ เช˜เชฃเชพ เชธเช‚เชธเซเช•เชฐเชฃเซ‹ เชธเชพเชฅเซ‡ เชธเชฎเชพเชชเซเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡เชจเซเช‚ เช•เชพเชฐเชฃ เชฌเชจเซ‡ เช›เซ‡. เชคเซ‡เชฅเซ€, เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‡ เชŸเซ‡เช•เซ‹ เช†เชชเชตเชพ เชฎเชพเชŸเซ‡ เช•เชพเชฐเซเชฏเช•เซเชทเชฎ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชœเชพเชณเชตเชตเชพเชฎเชพเช‚ เชธเช•เซเชทเชฎ เชฌเชจเชตเซเช‚ เช–เซ‚เชฌ เชœ เชฎเชนเชคเซเชตเชชเซ‚เชฐเซเชฃ เช›เซ‡.

เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“เชจเชพ เช‰เชชเชฏเซ‹เช—เชจเซ‡ เช‘เชชเซเชŸเชฟเชฎเชพเช‡เช เช•เชฐเชตเชพ เช…เชจเซ‡ เชธเซเชงเชพเชฐเชตเชพ เชฎเชพเชŸเซ‡ เช…เชนเซ€เช‚ เช•เซ‡เชŸเชฒเซ€เช• เชŸเซ€เชชเซเชธ เช†เชชเซ€ เช›เซ‡.

เชจเซ‹เช‚เชง: เชจเซ€เชšเซ‡ เชฆเชฐเซเชถเชพเชตเซ‡เชฒ เช•เซเชตเซ‡เชฐเซ€ เช…เชธเช‚เชถเซ‹เชงเชฟเชค เชชเชฐ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡ 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) เชœเซ‡เชจเซ€ เช•เซเชตเซ‡เชฐเซ€ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡.

เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ 11 เชฎเชพเช‚ เช•เชตเชฐเชฟเช‚เช— เช‡เชจเซเชกเซ‡เช•เซเชธ เชฐเชœเซ‚ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เช›เซ‡. เชคเซ‡เช“ เชคเชฎเชจเซ‡ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเชฎเชพเช‚ เชœ เชเช• เช…เชฅเชตเชพ เชตเชงเซ เชตเชงเชพเชฐเชพเชจเชพ เช•เซ‰เชฒเชฎเซเชธ เชถเชพเชฎเซ‡เชฒ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡ - เชคเซ‡เชฎเชจเชพ เชฎเซ‚เชฒเซเชฏเซ‹ เช‡เชจเซเชกเซ‡เช•เซเชธ เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐเชฎเชพเช‚ เชธเช‚เช—เซเชฐเชนเชฟเชค เชฅเชพเชฏ เช›เซ‡.

เชœเซ‹ เช…เชฎเซ‡ เช† เชธเซเชตเชฟเชงเชพเชจเซ‹ เชฒเชพเชญ เชฒเซ€เชงเซ‹ เช…เชจเซ‡ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเชจเซ€ เช…เช‚เชฆเชฐ เชˆเชฎเซ‡เชฒ เชฎเซ‚เชฒเซเชฏ เช‰เชฎเซ‡เชฐเซเชฏเซเช‚, เชคเซ‹ เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชธเซ‡ เชฎเซ‚เชฒเซเชฏ เชฎเชพเชŸเซ‡ เช•เซ‹เชทเซเชŸเช• เชขเช—เชฒเชพ เชถเซ‹เชงเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชฐเชนเซ‡เชถเซ‡ เชจเชนเซ€เช‚. 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เช…เชฎเชจเซ‡ เช•เชนเซ‡ เช›เซ‡ เช•เซ‡ เช•เซเชตเซ‡เชฐเซ€ เชฎเชพเชŸเซ‡ เชนเชตเซ‡ เชฎเชพเชคเซเชฐ เชเช• เช‡เชจเซเชกเซ‡เช•เซเชธเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡, เชœเซ‡ เช•เซ‹เชทเซเชŸเช•เชจเชพ เชขเช—เชฒเชพ เชตเชพเช‚เชšเชตเชพ เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฎ เชกเชฟเชธเซเช• I/O เชจเซ‡ เชŸเชพเชณเชตเชพเชฎเชพเช‚ เชฎเชฆเชฆ เช•เชฐเซ‡ เช›เซ‡.

เช•เชตเชฐเชฟเช‚เช— เช‡เชจเซเชกเซ‡เช•เซเชธ เชนเชพเชฒเชฎเชพเช‚ เชฎเชพเชคเซเชฐ 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 เชจเซ€ เช•เชฟเช‚เชฎเชค เชธเชพเชฅเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เชขเช—เชฒเซ‹ เชธเซเช•เซ‡เชจ เช•เชฐเชตเชพเชจเซ€ เชตเชฟเชจเช‚เชคเซ€ เช•เชฐเซ‡ เช›เซ‡.

เชšเชพเชฒเซ‹ เชœเซ‹เชˆเช เช•เซ‡ เชถเซเช‚ เชจเชฟเชฏเชฎเชฟเชค เชฌเซ€-เชŸเซเชฐเซ€ เช‡เชจเซเชกเซ‡เช•เซเชธ เช†เชชเชฃเชจเซ‡ เชฎเชฆเชฆ เช•เชฐเซ‡ เช›เซ‡:

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)

เช‡เชจเซเชกเซ‡เช•เซเชธ เชชเชฃ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เชจ เชนเชคเซ‹. เชฌเซ€-เชŸเซเชฐเซ€ เช‡เชจเซเชกเซ‡เช•เซเชธ เช…เชจเซเช•เซเชฐเชฎเชฟเชค เชฎเซ‚เชฒเซเชฏเซ‹เชฎเชพเช‚ เชตเซเชฏเช•เซเชคเชฟเช—เชค เช˜เชŸเช•เซ‹เชจเชพ เช…เชธเซเชคเชฟเชคเซเชตเชฅเซ€ เชตเชพเช•เซ‡เชซ เชจเชฅเซ€.

เช…เชฎเชจเซ‡ 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)

เชธเซเชชเชฐเชธเซ‡เชŸ เชธเซ‚เชšเช•เชพเช‚เช•เซ‹

เชเชตเซเช‚ เชฌเชจเซ€ เชถเช•เซ‡ เช›เซ‡ เช•เซ‡ เชคเชฎเซ‡ เช˜เชฃเชพ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“ เชธเชพเชฅเซ‡ เชธเชฎเชพเชชเซเชค เช•เชฐเซ‹ เช›เซ‹, เชœเซ‡เชฎเชพเช‚เชฅเซ€ เชเช• เช•เซ‰เชฒเชฎเชจเชพ เชธเซเชชเชฐเชธเซ‡เชŸเชจเซ‡ เช…เชจเซเช•เซเชฐเชฎเชฟเชค เช•เชฐเซ‡ เช›เซ‡ เชœเซ‡ เช…เชจเซเชฏ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“เชจเซ‡ เช…เชจเซเช•เซเชฐเชฎเชฟเชค เช•เชฐเซ‡ เช›เซ‡. เช† เช‡เชšเซเช›เชจเซ€เชฏ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡ เช…เชฅเชตเชพ เชจ เชชเชฃ เชนเซ‹เชˆ เชถเช•เซ‡-เชธเซเชชเชฐเชธเซ‡เชŸ เชฎเชพเชคเซเชฐ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพ เชธเซเช•เซ‡เชจเชฎเชพเช‚ เชชเชฐเชฟเชฃเชฎเซ€ เชถเช•เซ‡ เช›เซ‡, เชœเซ‡ เชธเชพเชฐเซเช‚ เช›เซ‡, เชชเชฐเช‚เชคเซ เชคเซ‡ เชตเชงเซ เชชเชกเชคเซ€ เชœเช—เซเชฏเชพ เชฒเชˆ เชถเช•เซ‡ เช›เซ‡, เช…เชฅเชตเชพ เชธเซเชชเชฐเชธเซ‡เชŸ เช‘เชชเซเชŸเชฟเชฎเชพเช‡เช เช•เชฐเชตเชพเชจเซ‹ เชนเซ‡เชคเซ เชนเชคเซ‹ เชคเซ‡ เช•เซเชตเซ‡เชฐเซ€ เชนเชตเซ‡ เช‰เชชเชฏเซ‹เช—เชฎเชพเช‚ เชฒเซ‡เชตเชพเชคเซ€ เชจเชฅเซ€.

เชœเซ‹ เชคเชฎเชพเชฐเซ‡ เช†เชตเชพ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“เชจเซ€ เชตเซเชฏเชพเช–เซเชฏเชพเชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเซ‡ เชชเซเชฐเชพเชฐเช‚เชญ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ 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

เช† เช‡เชจเซเชกเซ‡เช•เซเชธ เชฌเชจเชพเชตเชตเชพเชจเซ€ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชธเชพเชฎเชพเชจเซเชฏ เช•เชฐเชคเชพเช‚ เช…เชฒเช— เช›เซ‡ เชœเซ‡เชฎเชพเช‚ เชคเซ‡เชจเซ‡ เชŸเซ‡เชฌเชฒ เชชเชฐ เชฒเซ‰เช•เชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชคเซ€ เชจเชฅเซ€, เช…เชจเซ‡ เชคเซ‡เชฅเซ€ เชฒเซ‡เช–เชจ เช•เชพเชฎเช—เซ€เชฐเซ€เชจเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเชคเซ€ เชจเชฅเซ€. เชฌเซ€เชœเซ€ เชฌเชพเชœเซ, เชคเซ‡ เชตเชงเซ เชธเชฎเชฏ เชฒเซ‡ เช›เซ‡ เช…เชจเซ‡ เชตเชงเซ เชธเช‚เชธเชพเชงเชจเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡.

เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชธ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เช•เซ‹เชˆเชชเชฃ เชตเชฟเชถเชฟเชทเซเชŸ เช•เซ‡เชธเซ‹เชจเซ‡ เชนเชฒ เช•เชฐเชตเชพเชจเซ€ เชฐเซ€เชคเซ‹ เชคเซ‡เชฎเชœ เชคเชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชฟเชธเซเชซเซ‹เชŸเชฅเซ€ เชตเชงเซ‡ เชคเซ‹ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซเช‚ เชธเช‚เชšเชพเชฒเชจ เช•เชฐเชตเชพเชจเซ€ เชฐเซ€เชคเซ‹ เชฎเชพเชŸเซ‡ เช˜เชฃเซ€ เชฐเชพเชนเชค เชชเซ‚เชฐเซ€ เชชเชพเชกเซ‡ เช›เซ‡. เช…เชฎเซ‡ เช†เชถเชพ เชฐเชพเช–เซ€เช เช›เซ€เช เช•เซ‡ เช† เชŸเชฟเชชเซเชธ เชคเชฎเชจเซ‡ เชคเชฎเชพเชฐเซ€ เช•เซเชตเซ‡เชฐเซ€ เชเชกเชชเชฅเซ€ เชฎเซ‡เชณเชตเชตเชพเชฎเชพเช‚ เช…เชจเซ‡ เชคเชฎเชพเชฐเชพ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เชฎเชพเชชเชตเชพ เชฎเชพเชŸเซ‡ เชคเซˆเชฏเชพเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เชฎเชฆเชฆ เช•เชฐเชถเซ‡.

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹