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
'๋ ์ด์ ์ฟผ๋ฆฌ์ ์ธ๋ฑ์ค๋ง ํ์ํ๋ฏ๋ก ํ
์ด๋ธ ํ์ ์ฝ๊ธฐ ์ํ ๋ชจ๋ ๋์คํฌ 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
. ์ด๋ฌํ ๋ชจ๋ ์ํ๋ฅผ ๊ฒ์ํ๋ ค๋ฉด "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)
์์ ์งํฉ ์ธ๋ฑ์ค
๋ง์ ์ธ๋ฑ์ค๊ฐ ์๊ธธ ์ ์์ผ๋ฉฐ ๊ทธ ์ค ํ๋๋ ๋ค๋ฅธ ์ธ๋ฑ์ค๋ฅผ ์ธ๋ฑ์ฑํ๋ ์ด์ ์์ ์งํฉ์ ์ธ๋ฑ์ฑํฉ๋๋ค. ์ด๋ ๋ฐ๋์งํ ์๋ ์๊ณ ๋ฐ๋์งํ์ง ์์ ์๋ ์์ต๋๋ค. ์์ ์งํฉ์ ์ธ๋ฑ์ค ์ ์ฉ ์ค์บ์ ์์ฑํ ์ ์์ง๋ง ์ด๋ ์ข์ง๋ง ๋๋ฌด ๋ง์ ๊ณต๊ฐ์ ์ฐจ์งํ๊ฑฐ๋ ์์ ์งํฉ์ด ์ต์ ํํ๋ ค๋ ์ฟผ๋ฆฌ๊ฐ ๋ ์ด์ ์ฌ์ฉ๋์ง ์์ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ธ๋ฑ์ค์ ์ ์๋ฅผ ์๋ํํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ค์์ผ๋ก ์์ํ ์ ์์ต๋๋ค. 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๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ํญ๋ฐ์ ์ผ๋ก ์ฑ์ฅํ๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ๋ฟ๋ง ์๋๋ผ ํน๋ณํ ๊ฒฝ์ฐ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ๊ณผ ์์ธ ์์ฑ์ ์ํ ๋ง์ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค. ์ด ํ์ด ์ฟผ๋ฆฌ ์๋๋ฅผ ๋์ด๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ฅ์ ์ค๋นํ๋ ๋ฐ ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ถ์ฒ : habr.com