ΠšΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° ситС моТности Π½Π° индСкситС Π²ΠΎ PostgreSQL

ΠšΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° ситС моТности Π½Π° индСкситС Π²ΠΎ PostgreSQL
Π’ΠΎ свСтот Π½Π° Postgres, индСкситС сС ΠΊΠ»ΡƒΡ‡Π½ΠΈ Π·Π° Сфикасно Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡ˜Π° Π²ΠΎ ΡΠΊΠ»Π°Π΄ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ (Π½Π°Ρ€Π΅Ρ‡Π΅Π½ΠΎ Π³Ρ€Π°ΠΌΠ°Π΄Π°). Postgres Π½Π΅ ΠΏΠΎΠ΄Π΄Ρ€ΠΆΡƒΠ²Π° ΠΊΠ»Π°ΡΡ‚Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ Π·Π° Π½Π΅Π³ΠΎ, Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° MVCC ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΡƒΠ²Π° Π΄Π° Π·Π°Π²Ρ€ΡˆΠΈΡ‚Π΅ со ΠΌΠ½ΠΎΠ³Ρƒ Π²Π΅Ρ€Π·ΠΈΠΈ Π½Π° истата Ρ‚ΠΎΡ€ΠΊΠ°. Π—Π°Ρ‚ΠΎΠ°, ΠΌΠ½ΠΎΠ³Ρƒ Π΅ Π²Π°ΠΆΠ½ΠΎ Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ ΠΈ ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°Ρ‚Π΅ Сфикасни индСкси Π·Π° ΠΏΠΎΠ΄Π΄Ρ€ΡˆΠΊΠ° Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈΡ‚Π΅.

Π’ΠΈ прСнСсувам Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ совСти Π·Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°ΡšΠ΅ ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅Ρ‚ΠΎ Π½Π° индСкситС.

Π—Π°Π±Π΅Π»Π΅ΡˆΠΊΠ°: ΠŸΡ€Π°ΡˆΠ°ΡšΠ°Ρ‚Π° ΠΏΡ€ΠΈΠΊΠ°ΠΆΠ°Π½ΠΈ ΠΏΠΎΠ΄ΠΎΠ»Ρƒ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ Π½Π° Π½Π΅ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΊ ΠΎΠ΄ Π±Π°Π·Π°Ρ‚Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π½Π° ΠΏΠ°Π³ΠΈΠ»Π°.

ΠšΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° индСкси Π·Π° ΠΏΠΎΠΊΡ€ΠΈΠ²Π°ΡšΠ΅

АјдС Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Π²ΠΎ Π±Π°Ρ€Π°ΡšΠ΅Ρ‚ΠΎ Π·Π° Π²Ρ€Π°ΡœΠ°ΡšΠ΅ Π½Π° Π΅-ΠΏΠΎΡˆΡ‚Π° Π·Π° Π½Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈ корисници. Π’ΠΎ Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° 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β€œ, Π° ΠΏΠΎΡ‚ΠΎΠ° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Ρ‚Π΅ со ΠΏΡ€Π΅Π±Π°Ρ€ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΊΡƒΠΏΠΎΡ‚ Π½Π° Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° Π·Π° Π΄Π° Π³ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚Π΅ врСдноститС Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΠΊΠΎΠ»ΠΎΠ½ΠΈ (Π²ΠΎ овој ΡΠ»ΡƒΡ‡Π°Ρ˜, ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π° 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" Π½ΠΈ ΠΊΠ°ΠΆΡƒΠ²Π° Π΄Π΅ΠΊΠ° Π½Π° Π±Π°Ρ€Π°ΡšΠ΅Ρ‚ΠΎ сСга ΠΌΡƒ Ρ‚Ρ€Π΅Π±Π° само индСксот, ΡˆΡ‚ΠΎ ΠΏΠΎΠΌΠ°Π³Π° Π΄Π° сС ΠΈΠ·Π±Π΅Π³Π½Π°Ρ‚ ситС Π’/И Π½Π° дискот Π·Π° Π΄Π° сС ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π° ΠΊΡƒΠΏΠΎΡ‚ Π½Π° Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π°.

ДСнСс, индСкситС Π·Π° ΠΏΠΎΠΊΡ€ΠΈΠ²Π°ΡšΠ΅ сС достапни само Π·Π° Π‘-Π΄Ρ€Π²Π°Ρ‚Π°. ΠœΠ΅Ρ“ΡƒΡ‚ΠΎΠ°, Π²ΠΎ овој ΡΠ»ΡƒΡ‡Π°Ρ˜ Π½Π°ΠΏΠΎΡ€ΠΎΡ‚ Π·Π° ΠΎΠ΄Ρ€ΠΆΡƒΠ²Π°ΡšΠ΅ ќС Π±ΠΈΠ΄Π΅ ΠΏΠΎΠ³ΠΎΠ»Π΅ΠΌ.

ΠšΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° ΠΏΠ°Ρ€Ρ†ΠΈΡ˜Π°Π»Π½ΠΈ индСкси

Π”Π΅Π»ΡƒΠΌΠ½ΠΈΡ‚Π΅ индСкси индСксираат само подмноТСство ΠΎΠ΄ Ρ€Π΅Π΄ΠΎΠ²ΠΈΡ‚Π΅ Π½Π° Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π°. Ова Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° ја Π·Π°Ρ‡ΡƒΠ²Π°Ρ‚Π΅ Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°Ρ‚Π° Π½Π° индСксот ΠΈ Π΄Π° Π²Ρ€ΡˆΠΈΡ‚Π΅ ΡΠΊΠ΅Π½ΠΈΡ€Π°ΡšΠ΅ ΠΏΠΎΠ±Ρ€Π·ΠΎ.

Π”Π° Ρ€Π΅Ρ‡Π΅ΠΌΠ΅ Π΄Π΅ΠΊΠ° Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π΄ΠΎΠ±ΠΈΠ΅ΠΌΠ΅ список со адрСси Π½Π° Π΅-ΠΏΠΎΡˆΡ‚Π° Π·Π° Π½Π°ΡˆΠΈΡ‚Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΈ Π²ΠΎ ΠšΠ°Π»ΠΈΡ„ΠΎΡ€Π½ΠΈΡ˜Π°. Π‘Π°Ρ€Π°ΡšΠ΅Ρ‚ΠΎ ќС Π±ΠΈΠ΄Π΅ Π²Π°ΠΊΠ°:

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. Π—Π° Π΄Π° Π³ΠΈ Π±Π°Ρ€Π°ΠΌΠ΅ ситС Ρ‚Π°ΠΊΠ²ΠΈ Ρ„ΠΈΠ»ΠΌΠΎΠ²ΠΈ, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΈ ΠΈΠ·Π±Π΅Ρ€Π΅ΠΌΠ΅ ситС Ρ€Π΅Π΄ΠΎΠ²ΠΈ со β€ž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

Оваа постапка Π·Π° создавањС индСкс сС Ρ€Π°Π·Π»ΠΈΠΊΡƒΠ²Π° ΠΎΠ΄ Π²ΠΎΠΎΠ±ΠΈΡ‡Π°Π΅Π½Π°Ρ‚Π° ΠΏΠΎ Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ Π½Π΅ Π±Π°Ρ€Π° Π·Π°ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π°ΡšΠ΅ Π½Π° Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° ΠΈ Π·Π°Ρ‚ΠΎΠ° Π½Π΅ Π³ΠΈ Π±Π»ΠΎΠΊΠΈΡ€Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈΡ‚Π΅ Π·Π° Π·Π°ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅. Од Π΄Ρ€ΡƒΠ³Π° страна, Ρ‚ΠΎΠ° Ρ‚Ρ€Π°Π΅ ΠΏΠΎΠ΄ΠΎΠ»Π³ΠΎ ΠΈ Ρ‚Ρ€ΠΎΡˆΠΈ повСќС рСсурси.

Postgres ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡƒΠ²Π° ΠΌΠ½ΠΎΠ³Ρƒ флСксибилни ΠΎΠΏΡ†ΠΈΠΈ Π·Π° ΠΊΡ€Π΅ΠΈΡ€Π°ΡšΠ΅ индСкси ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ˜Π° Π·Π° ΠΊΠ°ΠΊΠ²ΠΈ Π±ΠΈΠ»ΠΎ посСбни случаи, Π° исто Ρ‚Π°ΠΊΠ° ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡƒΠ²Π° Π½Π°Ρ‡ΠΈΠ½ΠΈ Π·Π° ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°ΡšΠ΅ со Π±Π°Π·Π°Ρ‚Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π΄ΠΎΠΊΠΎΠ»ΠΊΡƒ Π²Π°ΡˆΠ°Ρ‚Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° Сксплозивно растС. Π‘Π΅ Π½Π°Π΄Π΅Π²Π°ΠΌΠ΅ Π΄Π΅ΠΊΠ° ΠΎΠ²ΠΈΠ΅ совСти ќС Π²ΠΈ ΠΏΠΎΠΌΠΎΠ³Π½Π°Ρ‚ Π΄Π° Π³ΠΈ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Π²Π°ΡˆΠΈΡ‚Π΅ Π±Π°Ρ€Π°ΡšΠ° Π±Ρ€Π·ΠΎ ΠΈ Π²Π°ΡˆΠ°Ρ‚Π° Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π΄Π° Π±ΠΈΠ΄Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²Π΅Π½Π° Π·Π° скала.

Π˜Π·Π²ΠΎΡ€: www.habr.com

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€