เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ„เบธเบ™เบชเบปเบกเบšเบฑเบ”เบ—เบฑเบ‡เบซเบกเบปเบ”เบ‚เบญเบ‡เบ”เบฑเบ”เบชเบฐเบ™เบตเปƒเบ™ PostgreSQL

เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ„เบธเบ™เบชเบปเบกเบšเบฑเบ”เบ—เบฑเบ‡เบซเบกเบปเบ”เบ‚เบญเบ‡เบ”เบฑเบ”เบชเบฐเบ™เบตเปƒเบ™ PostgreSQL
เปƒเบ™เป‚เบฅเบ Postgres, เบ”เบฑเบ”เบŠเบฐเบ™เบตเปเบกเปˆเบ™เบกเบตเบ„เบงเบฒเบกเบˆเปเบฒเป€เบ›เบฑเบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ™เปเบฒเบ—เบฒเบ‡เบ—เบตเปˆเบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบ‚เบญเบ‡เบเบฒเบ™เป€เบเบฑเบšเบฎเบฑเบเบชเบฒเบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™ (เป€เบญเบตเป‰เบ™เบงเปˆเบฒ "heap"). Postgres เบšเปเปˆเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบเบฒเบ™เบˆเบฑเบ”เบเบธเปˆเบกเบชเปเบฒเบฅเบฑเบšเบกเบฑเบ™, เปเบฅเบฐเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒ MVCC เป€เบฎเบฑเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เบชเบดเป‰เบ™เบชเบธเบ”เบ”เป‰เบงเบ tuple เบ”เบฝเบงเบเบฑเบ™เบซเบผเบฒเบเบฎเบธเปˆเบ™. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบดเปˆเบ‡เบชเปเบฒเบ„เบฑเบ™เบซเบผเบฒเบเบ—เบตเปˆเบˆเบฐเบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เปเบฅเบฐเบฎเบฑเบเบชเบฒเบ”เบฑเบ”เบชเบฐเบ™เบตเบ—เบตเปˆเบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเป€เบžเบทเปˆเบญเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบ.

เบ™เบตเป‰เปเบกเปˆเบ™เบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบšเบฒเบ‡เบขเปˆเบฒเบ‡เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเปเบฅเบฐเบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ”เบฑเบ”เบชเบฐเบ™เบต.

เบซเบกเบฒเบเป€เบซเบ”: เบ„เปเบฒเบ–เบฒเบกเบ—เบตเปˆเบชเบฐเปเบ”เบ‡เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เป€เบฎเบฑเบ”เบงเบฝเบเบขเบนเปˆเปƒเบ™ unmodified เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡ 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". เบ™เบตเป‰เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒ Postgres เบˆเบฐเบชเบฐเปเบเบ™เบ”เบฑเบ”เบชเบฐเบ™เบต "idx_cust1", เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบชเบทเบšเบ•เปเปˆเบŠเบญเบเบซเบฒ heap เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เป€เบžเบทเปˆเบญเบญเปˆเบฒเบ™เบ„เปˆเบฒเบ‚เบญเบ‡เบ–เบฑเบ™เบญเบทเปˆเบ™เป† (เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰, เบ–เบฑเบ™. email) เบ—เบตเปˆโ€‹เบเบฒเบ™โ€‹เบชเบญเบšโ€‹เบ–เบฒเบกโ€‹เบ•เป‰เบญเบ‡โ€‹เบเบฒเบ™โ€‹.

เบเบฒเบ™เบ›เบปเบเบซเบธเป‰เบกเบ‚เบญเบ‡เบ”เบฑเบ”เบŠเบฐเบ™เบตเปเบกเปˆเบ™เป„เบ”เป‰เบ™เปเบฒเบชเบฐเป€เบซเบ™เบตเปƒเบ™ PostgreSQL 11. เบžเบงเบเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เบ›เบฐเบเบญเบšเบซเบ™เบถเปˆเบ‡เบซเบผเบทเบซเบผเบฒเบเบ„เปเบฅเปเบฒเป€เบžเบตเปˆเบกเป€เบ•เบตเบกเปƒเบ™เบ”เบฑเบ”เบŠเบฐเบ™เบตเบ•เบปเบงเบกเบฑเบ™เป€เบญเบ‡ - เบกเบนเบ™เบ„เปˆเบฒเบ‚เบญเบ‡เบžเบงเบเบกเบฑเบ™เบ–เบทเบเป€เบเบฑเบšเป„เบงเป‰เปƒเบ™เบšเปˆเบญเบ™เป€เบเบฑเบšเบ‚เปเป‰เบกเบนเบ™เบ”เบฑเบ”เบชเบฐเบ™เบต.

เบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเปƒเบŠเป‰เบ›เบฐเป‚เบซเบเบ”เบˆเบฒเบเบ„เบธเบ™เบชเบปเบกเบšเบฑเบ”เบ™เบตเป‰เปเบฅเบฐเป€เบžเบตเปˆเบกเบกเบนเบ™เบ„เปˆเบฒเบญเบตเป€เบกเบฅเปŒเบžเบฒเบเปƒเบ™เบ”เบฑเบ”เบชเบฐเบ™เบต, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™ Postgres เบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบ„เบปเป‰เบ™เบซเบฒ heap เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบชเปเบฒเบฅเบฑเบšเบกเบนเบ™เบ„เปˆเบฒ. 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' เบšเบญเบเบžเบงเบเป€เบฎเบปเบฒเบงเปˆเบฒ query เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบžเบฝเบ‡เปเบ•เปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เบ”เบฑเบ”เบชเบฐเบ™เบต, เป€เบŠเบดเปˆเบ‡เบŠเปˆเบงเบเบซเบฅเบตเบเบฅเปˆเบฝเบ‡ disk I/O เบ—เบฑเบ‡เบซเบกเบปเบ”เป€เบžเบทเปˆเบญเบญเปˆเบฒเบ™ heap เบ•เบฒเบ•เบฐเบฅเบฒเบ‡.

เบ”เบฑเบ”เบŠเบฐเบ™เบตเบเบฒเบ™เบ›เบปเบเบ„เบธเบกเปเบกเปˆเบ™เบกเบตเบžเบฝเบ‡เปเบ•เปˆเบชเปเบฒเบฅเบฑเบš B-trees เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰, เบ„เบงเบฒเบกเบžเบฐเบเบฒเบเบฒเบกเบšเปเบฒเบฅเบธเบ‡เบฎเบฑเบเบชเบฒเบˆเบฐเบชเบนเบ‡เบ‚เบถเป‰เบ™.

เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เบ”เบฑเบ”โ€‹เบŠเบฐโ€‹เบ™เบตโ€‹เบšเบฒเบ‡โ€‹เบชเปˆเบงเบ™โ€‹

เบ”เบฑเบ”เบชเบฐเบ™เบตเบšเบฒเบ‡เบชเปˆเบงเบ™เบžเบฝเบ‡เปเบ•เปˆเบ”เบฑเบ”เบชเบฐเบ™เบตเบเปˆเบญเบเบ‚เบญเบ‡เปเบ–เบงเปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡. เบ™เบตเป‰เบŠเปˆเบงเบเบ›เบฐเบขเบฑเบ”เบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡เบ”เบฑเบ”เบชเบฐเบ™เบตเปเบฅเบฐเป€เบฎเบฑเบ”เปƒเบซเป‰เบเบฒเบ™เบชเบฐเปเบเบ™เป„เบงเบ‚เบถเป‰เบ™.

เปƒเบซเป‰เป€เบงเบปเป‰เบฒเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเป„เบ”เป‰เบฎเบฑเบšเบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆเบ‚เบญเบ‡เบ—เบตเปˆเบขเบนเปˆเบญเบตเป€เบกเบงเบ‚เบญเบ‡เบฅเบนเบเบ„เป‰เบฒเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเปƒเบ™เบ„เบฒเบฅเบดเบŸเปเป€เบ™เบ. เบ„เปเบฒโ€‹เบฎเป‰เบญเบ‡โ€‹เบชเบฐโ€‹เบซเบกเบฑเบโ€‹เบˆเบฐโ€‹เป€เบ›เบฑเบ™โ€‹เบ”เบฑเปˆเบ‡โ€‹เบ™เบตเป‰โ€‹:

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)

Scan address เป„เบ”เป‰เบ–เบทเบเปเบ—เบ™เบ—เบตเปˆเป‚เบ”เบเบเบฒเบ™เบชเบฐเปเบเบ™เบ”เบฑเบ”เบชเบฐเบ™เบต idx_address1เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบชเบฐเปเบเบ™ heap 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.

เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เบ”เบฑเบ”โ€‹เบŠเบฐโ€‹เบ™เบตโ€‹เบซเบผเบฒเบโ€‹เบ„เบธเบ™โ€‹เบ„เปˆเบฒโ€‹

เบšเบฒเบ‡เบ–เบฑเบ™เบ—เบตเปˆเบˆเบฐเบ–เบทเบเบ”เบฑเบ”เบชเบฐเบ™เบตเบญเบฒเบ”เบˆเบฐเบšเปเปˆเบกเบตเบ›เบฐเป€เบžเบ”เบ‚เปเป‰เบกเบนเบ™ scalar. เบ›เบฐเป€เบžเบ”เบ–เบฑเบ™เป€เบŠเบฑเปˆเบ™ jsonb, arrays ะธ tsvector เบกเบตเบ„เปˆเบฒเบ›เบฐเบชเบปเบก เบซเบผเบทเบซเบผเบฒเบเบ„เปˆเบฒ. เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบ”เบฑเบ”เบชเบฐเบ™เบตเบ„เปเบฅเปเบฒเบ”เบฑเปˆเบ‡เบเปˆเบฒเบง, เบ›เบปเบเบเบฐเบ•เบดเปเบฅเป‰เบงเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบ„เบปเป‰เบ™เบซเบฒเบกเบนเบ™เบ„เปˆเบฒเบชเปˆเบงเบ™เบšเบธเบเบ„เบปเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เปƒเบ™เบ„เปเบฅเปเบฒเป€เบซเบผเบปเปˆเบฒเบ™เบฑเป‰เบ™.

เปƒเบซเป‰เบžเบฐเบเบฒเบเบฒเบกเบŠเบญเบเบซเบฒเบซเบปเบงเบ‚เปเป‰เบ‚เบญเบ‡เบฎเบนเบšเป€เบ‡เบปเบฒเบ—เบฑเบ‡เบซเบกเบปเบ”เบ—เบตเปˆเบกเบตเบเบฒเบ™เบ•เบฑเบ”เบˆเบฒเบเบเบฒเบ™เปƒเบŠเป‰เป€เบงเบฅเบฒเบ—เบตเปˆเบšเปเปˆเบชเปเบฒเป€เบฅเบฑเบ”. เบ•เบฒเบ•เบฐเบฅเบฒเบ‡ film เบกเบตเบ–เบฑเบ™เบ‚เปเป‰เบ„เบงเบฒเบกเบ—เบตเปˆเป€เบญเบตเป‰เบ™เบงเปˆเบฒ special_features. เบ–เป‰เบฒเบฎเบนเบšเป€เบ‡เบปเบฒเบกเบต "เบ„เบธเบ™เบชเบปเบกเบšเบฑเบ”เบžเบดเป€เบชเบ”", เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ„เปเบฅเปเบฒเบ›เบฐเบเบญเบšเบ”เป‰เบงเบเบญเบปเบ‡เบ›เบฐเบเบญเบšเป€เบ›เบฑเบ™ array เบ‚เปเป‰เบ„เบงเบฒเบก Behind The Scenes. เป€เบžเบทเปˆเบญเบŠเบญเบเบซเบฒเบฎเบนเบšเป€เบ‡เบปเบฒเบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเบ—เบฑเบ‡เบซเบกเบปเบ”, เบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป€เบฅเบทเบญเบเปเบ–เบงเบ—เบฑเบ‡เบซเบกเบปเบ”เบ—เบตเปˆเบกเบต "Behind The Scenes" เปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆ เปƒเบ”เป† เบ„เปˆเบฒ array 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)

เป€เบŠเบดเปˆเบ‡เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบชเบฐเปเบเบ™ heap เป€เบ•เบฑเบกเบ—เบตเปˆเบกเบตเบ„เปˆเบฒเปƒเบŠเป‰เบˆเปˆเบฒเบ 67.

เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบงเปˆเบฒเบ”เบฑเบ”เบŠเบฐเบ™เบต B-tree เบ›เบปเบเบเบฐเบ•เบดเบŠเปˆเบงเบเบžเบงเบเป€เบฎเบปเบฒ:

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-tree เบšเปเปˆเบฎเบนเป‰เป€เบ–เบดเบ‡เบเบฒเบ™เบกเบตเบขเบนเปˆเบ‚เบญเบ‡เบญเบปเบ‡เบ›เบฐเบเบญเบšเปเบ•เปˆเบฅเบฐเบญเบฑเบ™เปƒเบ™เบ„เปˆเบฒเบ—เบตเปˆเบ–เบทเบเบ”เบฑเบ”เบชเบฐเบ™เบต.

เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบ”เบฑเบ”เบŠเบฐเบ™เบต 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

เบกเบฑเบ™เบชเบฒเบกเบฒเบ”เป€เบเบตเบ”เบ‚เบทเป‰เบ™เป„เบ”เป‰เบงเปˆเบฒเบ—เปˆเบฒเบ™เบชเบดเป‰เบ™เบชเบธเบ”เบ”เป‰เบงเบเบ”เบฑเบ”เบชเบฐเบ™เบตเบซเบผเบฒเบ, เบซเบ™เบถเปˆเบ‡เปƒเบ™เบ™เบฑเป‰เบ™เบ”เบฑเบ”เบชเบฐเบ™เบต superset เบ‚เบญเบ‡เบ–เบฑเบ™เบ—เบตเปˆเบ”เบฑเบ”เบชเบฐเบ™เบตเบ”เบฑเบ”เบชเบฐเบ™เบตเบญเบทเปˆเบ™เป†. เบญเบฑเบ™เบ™เบตเป‰เบญเบฒเบ”เบˆเบฐเบ•เป‰เบญเบ‡เบเบฒเบ™ เบซเบผเบทเบญเบฒเบ”เบˆเบฐเบšเปเปˆเบขเบฒเบเป„เบ”เป‰ - เบŠเบธเบšเป€เบ›เบตเป€เบŠเบ”เบญเบฒเบ”เบˆเบฐเบชเบปเปˆเบ‡เบœเบปเบ™เปƒเบซเป‰เบกเบตเบเบฒเบ™เบชเบฐเปเบเบ™เปเบšเบšเบ”เบฑเบ”เบชเบฐเบ™เบตเป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™, เป€เบŠเบดเปˆเบ‡เป€เบ›เบฑเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบ”เบต, เปเบ•เปˆเบกเบฑเบ™เบญเบฒเบ”เบˆเบฐเปƒเบŠเป‰เบžเบทเป‰เบ™เบ—เบตเปˆเบซเบผเบฒเบเป€เบเบตเบ™เป„เบ›, เบซเบผเบทเบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบ—เบตเปˆ superset เบกเบตเบˆเบธเบ”เบ›เบฐเบชเบปเบ‡เป€เบžเบทเปˆเบญเป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบˆเบฐเบšเปเปˆเบ–เบทเบเปƒเบŠเป‰เบญเบตเบเบ•เปเปˆเป„เบ›.

เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เบ„เปเบฒเบ™เบดเบเบฒเบกเบ‚เบญเบ‡เบ”เบฑเบ”เบชเบฐเบ™เบตเบ”เบฑเปˆเบ‡เบเปˆเบฒเบง, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ”เป‰เบงเบ pg_index เบˆเบฒเบเบ•เบฒเบ•เบฐเบฅเบฒเบ‡ pg_catalog.

เบ”เบฑเบ”เบŠเบฐเบ™เบตเบ—เบตเปˆเบšเปเปˆเป„เบ”เป‰เปƒเบŠเป‰

เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเปเบญเบฑเบšเบžเบฅเบดเป€เบ„เบŠเบฑเบ™เบ—เบตเปˆเปƒเบŠเป‰เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบ—เบตเปˆเบžเบงเบเป€เบ‚เบปเบฒเปƒเบŠเป‰. เบ”เบฑเบ”เบŠเบฐเบ™เบตเบ—เบตเปˆเป€เบžเบตเปˆเบกเปƒเบชเปˆเบเปˆเบญเบ™เปœเป‰เบฒเบ™เบตเป‰เบญเบฒเบ”เบˆเบฐเบšเปเปˆเบ–เบทเบเปƒเบŠเป‰เป‚เบ”เบเบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเปƒเบ”เป†. เปเบ•เปˆเบฅเบฐเบ„เบฑเป‰เบ‡เบ—เบตเปˆเบ”เบฑเบ”เบชเบฐเบ™เบตเบ–เบทเบเบชเบฐเปเบเบ™, เบกเบฑเบ™เบ–เบทเบเบซเบกเบฒเบเป‚เบ”เบเบœเบนเป‰เบˆเบฑเบ”เบเบฒเบ™เบชเบฐเบ–เบดเบ•เบด, เปเบฅเบฐเปƒเบ™เบกเบธเบกเบกเบญเบ‡เบ‚เบญเบ‡เบฅเบฐเบšเบปเบš pg_stat_user_indexes เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบšเบดเปˆเบ‡เบกเบนเบ™เบ„เปˆเบฒ idx_scan, เป€เบŠเบดเปˆเบ‡เป€เบ›เบฑเบ™เบ•เบปเบงเบ™เบฑเบšเบชเบฐเบชเบปเบก. เบเบฒเบ™เบ•เบดเบ”เบ•เบฒเบกเบกเบนเบ™เบ„เปˆเบฒเบ™เบตเป‰เปƒเบ™เป„เบฅเบเบฐเป€เบงเบฅเบฒ (เป€เบงเบปเป‰เบฒเป€เบ›เบฑเบ™เป€เบ”เบทเบญเบ™) เบˆเบฐเปƒเบซเป‰เบ„เบงเบฒเบกเบ„เบดเบ”เบ—เบตเปˆเบ”เบตเบ‚เบญเบ‡เบ”เบฑเบ”เบชเบฐเบ™เบตเบ—เบตเปˆเบšเปเปˆเป„เบ”เป‰เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เปเบฅเบฐเบญเบฒเบ”เบˆเบฐเบ–เบทเบเบซเบผเบธเบ”เบฅเบปเบ‡.

เบ™เบตเป‰เปเบกเปˆเบ™เบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเป€เบžเบทเปˆเบญเบฎเบฑเบšเป€เบญเบปเบฒเบเบฒเบ™เบชเบฐเปเบเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบ‚เบญเบ‡เบ”เบฑเบ”เบŠเบฐเบ™เบตเบ—เบฑเบ‡เปเบปเบ”เปƒเบ™ schema โ€˜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

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™