๋ช๋ฌ ์
๊ทธ ์ดํ๋ก ์ด๋ฏธ 6000ํ ์ด์ ์ฌ์ฉํ์ง๋ง ๊ฐ๊ณผํ ์ ์๋ ํธ๋ฆฌํ ๊ธฐ๋ฅ ์ค ํ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๊ตฌ์กฐ์ ๋จ์, ๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค.
๊ทธ๋ค์๊ฒ ๊ท๋ฅผ ๊ธฐ์ธ์ด๋ฉด ๊ทํ์ ์์ฒญ์ด "๋งค๋๋ฌ์์ง ๊ฒ"์
๋๋ค. ๐
๊ทธ๋ฌ๋ ์ง์งํ๊ฒ ์์ฒญ์ ๋๋ฆฌ๊ณ ๋ฆฌ์์ค ์ธก๋ฉด์์ "๊ฒ๊ฑธ์ค๋ฝ๊ฒ" ๋ง๋๋ ๋ง์ ์ํฉ, ์ผ๋ฐ์ ์ด๋ฉฐ ๊ณํ์ ๊ตฌ์กฐ์ ๋ฐ์ดํฐ๋ก ์ธ์ํ ์ ์์ต๋๋ค..
์ด ๊ฒฝ์ฐ ๊ฐ๋ณ ๊ฐ๋ฐ์๋ ์์ ์ ๊ฒฝํ์๋ง ์์กดํ์ฌ ์ค์ค๋ก ์ต์ ํ ์ต์ ์ ์ฐพ์ ํ์๊ฐ ์์ต๋๋ค. ์ฌ๊ธฐ์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง, ์ด์ ๊ฐ ๋ฌด์์ธ์ง, ํด๊ฒฐ์ฑ ์ ๋ด๋๋ ๋ฐฉ๋ฒ. ์ฐ๋ฆฌ๊ฐ ํ ์ผ์ ๋๋ค.
์ด๋ฌํ ๊ฒฝ์ฐ๊ฐ ์ด๋ป๊ฒ ์ ์๋๊ณ ์ด๋ค ๊ถ์ฅ ์ฌํญ์ผ๋ก ์ด์ด์ง๋์ง ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ฃผ์ ์ ๋ ์ ๋ชฐ์
ํ๋ ค๋ฉด ๋จผ์ ๋ค์์์ ํด๋น ๋ธ๋ก์ ๋ค์ ์ ์์ต๋๋ค.
์ธ๋ฑ์ค "undersort" ์ธ๋ฑ์ค ๊ต์ฐจ(BitmapAnd) ์ธ๋ฑ์ค ํฉ์งํฉ(BitmapOr) ๋๋ฌด ๋ง์ด ์ฝ๋ค ์คํ์ค ํ ์ด๋ธ ์์ธ์ "์ค๊ฐ"์์ ์ฝ๊ธฐ CTE ร CTE ๋์คํฌ๋ก ์ค์(์์ ์ฐ๊ธฐ) ์ค๋๋ ํต๊ณ "๋ญ๊ฐ ์๋ชป๋์ด"
#1: ์ธ๋ฑ์ค "undersorting"
์ธ์
ํด๋ผ์ด์ธํธ "LLC Kolokolchik"์ ๋ํ ๋ง์ง๋ง ์ก์ฅ์ ํ์ํฉ๋๋ค.
์๋ณ ๋ฐฉ๋ฒ
-> Limit
-> Sort
-> Index [Only] Scan [Backward] | Bitmap Heap Scan
์ถ์ฒ
์ฌ์ฉ๋ ์ธ๋ฑ์ค ์ ๋ ฌ ํ๋๋ก ํ์ฅ.
์ :
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ัะฐะบัะพะฒ"
, (random() * 1000)::integer fk_cli; -- 1K ัะฐะทะฝัั
ะฒะฝะตัะฝะธั
ะบะปััะตะน
CREATE INDEX ON tbl(fk_cli); -- ะธะฝะดะตะบั ะดะปั foreign key
SELECT
*
FROM
tbl
WHERE
fk_cli = 1 -- ะพัะฑะพั ะฟะพ ะบะพะฝะบัะตัะฝะพะน ัะฒัะทะธ
ORDER BY
pk DESC -- ั
ะพัะธะผ ะฒัะตะณะพ ะพะดะฝั "ะฟะพัะปะตะดะฝัั" ะทะฐะฟะธัั
LIMIT 1;
์ธ๋ฑ์ค์์ 100๊ฐ ์ด์์ ๋ ์ฝ๋๋ฅผ ๋บ ๋ค์ ๋ชจ๋ ์ ๋ ฌํ ๋ค์ ํ๋๋ง ๋จ์ ๋ ์ฝ๋๋ฅผ ์ฆ์ ์ ์ ์์ต๋๋ค.
์์ :
DROP INDEX tbl_fk_cli_idx;
CREATE INDEX ON tbl(fk_cli, pk DESC); -- ะดะพะฑะฐะฒะธะปะธ ะบะปัั ัะพััะธัะพะฒะบะธ
๊ทธ๋ฌํ ์์์ ์ํ์์๋ - 8.5๋ฐฐ ๋ ๋น ๋ฅด๊ณ 33๋ฐฐ ๋ ์ ์ ์ฝ๊ธฐ. ๊ฐ ๊ฐ์ ๋ํ "์ฌ์ค"์ด ๋ง์์๋ก ํจ๊ณผ๊ฐ ๋ ๋ช
ํํด์ง๋๋ค. fk
.
์ด๋ฌํ ์ธ๋ฑ์ค๋ ๋ค๋ฅธ ์ฟผ๋ฆฌ์ ๋ํด ์ด์ ์ธ๋ฑ์ค๋ณด๋ค ๋์์ง ์์ "์ ๋์ฌ" ์ธ๋ฑ์ค๋ก ์๋ํฉ๋๋ค. fk
, ์ฌ๊ธฐ์ ์ ๋ ฌ ๊ธฐ์ค pk
์๋์๋ค ๊ทธ๋ฆฌ๊ณ ์๋๋ค (๋น์ ์ ์ด๊ฒ์ ๋ํด ๋ ์ฝ์ ์ ์์ต๋๋ค
#2: ์ธ๋ฑ์ค ๊ต์ฐจ(BitmapAnd)
์ธ์
"NJSC Lyutik"์ ๋์ ํ์ฌ ์ฒด๊ฒฐ๋ ํด๋ผ์ด์ธํธ "LLC Kolokolchik"์ ๋ํ ๋ชจ๋ ๊ณ์ฝ์ ํ์ํฉ๋๋ค.
์๋ณ ๋ฐฉ๋ฒ
-> BitmapAnd
-> Bitmap Index Scan
-> Bitmap Index Scan
์ถ์ฒ
์์ฑ ๋ณตํฉ ์ง์ ๋ ์์ค์ ํ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๊ฑฐ๋ ๋ ๋ฒ์งธ์์ ๊ธฐ์กด ํ๋ ์ค ํ๋๋ฅผ ํ์ฅํฉ๋๋ค.
์ :
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ัะฐะบัะพะฒ"
, (random() * 100)::integer fk_org -- 100 ัะฐะทะฝัั
ะฒะฝะตัะฝะธั
ะบะปััะตะน
, (random() * 1000)::integer fk_cli; -- 1K ัะฐะทะฝัั
ะฒะฝะตัะฝะธั
ะบะปััะตะน
CREATE INDEX ON tbl(fk_org); -- ะธะฝะดะตะบั ะดะปั foreign key
CREATE INDEX ON tbl(fk_cli); -- ะธะฝะดะตะบั ะดะปั foreign key
SELECT
*
FROM
tbl
WHERE
(fk_org, fk_cli) = (1, 999); -- ะพัะฑะพั ะฟะพ ะบะพะฝะบัะตัะฝะพะน ะฟะฐัะต
์์ :
DROP INDEX tbl_fk_org_idx;
CREATE INDEX ON tbl(fk_org, fk_cli);
์ฌ๊ธฐ์ ๋นํธ๋งต ํ ์ค์บ์ ๊ทธ ์์ฒด๋ก ๋งค์ฐ ํจ๊ณผ์ ์ด๊ธฐ ๋๋ฌธ์ ์ด๋์ด ๋ ์์ต๋๋ค. ํ์ง๋ง ์ด์จ๋ 7๋ฐฐ ๋ ๋น ๋ฅด๊ณ 2.5๋ฐฐ ๋ ์ ์ ์ฝ๊ธฐ.
#3: ์ธ๋ฑ์ค ๊ฒฐํฉ(BitmapOr)
์ธ์
๊ฐ์ฅ ์ค๋๋ "์์ " ๋๋ ํ ๋น๋์ง ์์ ์ฒ๋ฆฌ ์์ฒญ 20๊ฐ๋ฅผ ์ฐ์ ์์๋ก ํ์ํฉ๋๋ค.
์๋ณ ๋ฐฉ๋ฒ
-> BitmapOr
-> Bitmap Index Scan
-> Bitmap Index Scan
์ถ์ฒ
์ฌ์ฉ ์ ๋์จ [์ ์ฒด] ๊ฐ ์กฐ๊ฑด OR ๋ธ๋ก์ ๋ํ ํ์ ์ฟผ๋ฆฌ๋ฅผ ๊ฒฐํฉํฉ๋๋ค.
์ :
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ัะฐะบัะพะฒ"
, CASE
WHEN random() < 1::real/16 THEN NULL -- ั ะฒะตัะพััะฝะพัััั 1:16 ะทะฐะฟะธัั "ะฝะธััั"
ELSE (random() * 100)::integer -- 100 ัะฐะทะฝัั
ะฒะฝะตัะฝะธั
ะบะปััะตะน
END fk_own;
CREATE INDEX ON tbl(fk_own, pk); -- ะธะฝะดะตะบั ั "ะฒัะพะดะต ะบะฐะบ ะฟะพะดั
ะพะดััะตะน" ัะพััะธัะพะฒะบะพะน
SELECT
*
FROM
tbl
WHERE
fk_own = 1 OR -- ัะฒะพะธ
fk_own IS NULL -- ... ะธะปะธ "ะฝะธััะธ"
ORDER BY
pk
, (fk_own = 1) DESC -- ัะฝะฐัะฐะปะฐ "ัะฒะพะธ"
LIMIT 20;
์์ :
(
SELECT
*
FROM
tbl
WHERE
fk_own = 1 -- ัะฝะฐัะฐะปะฐ "ัะฒะพะธ" 20
ORDER BY
pk
LIMIT 20
)
UNION ALL
(
SELECT
*
FROM
tbl
WHERE
fk_own IS NULL -- ะฟะพัะพะผ "ะฝะธััะธ" 20
ORDER BY
pk
LIMIT 20
)
LIMIT 20; -- ะฝะพ ะฒัะตะณะพ - 20, ะฑะพะปััะต ะธ ะฝะต ะฝะฐะดะพ
์ฐ๋ฆฌ๋ 20๊ฐ์ ํ์ํ ๋ ์ฝ๋๊ฐ ๋ชจ๋ ์ฒซ ๋ฒ์งธ ๋ธ๋ก์์ ์ฆ์ ์ป์ด์ก๋ค๋ ์ฌ์ค์ ์ด์ฉํ์ต๋๋ค. ๋ฐ๋ผ์ ๋ "๋น์ผ" Bitmap Heap Scan์ด ํฌํจ๋ ๋ ๋ฒ์งธ ๋ธ๋ก์ ์คํ์กฐ์ฐจ ๋์ง ์์์ต๋๋ค. 22๋ฐฐ ๋ ๋น ๋ฅด๊ณ 44๋ฐฐ ๋ ์ ์ ์ฝ๊ธฐ!
์ด ์ต์ ํ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ์ด์ผ๊ธฐ ๊ตฌ์ฒด์ ์ธ ์ฌ๋ก์ ๋ํด ๊ธฐ์ฌ์์ ์ฝ์ ์ ์์ต๋๋ค
PostgreSQL ์ํฐํจํด: ์ ํดํ JOIN ๋ฐ OR ะธPostgreSQL ์ํฐํจํด: ์ด๋ฆ๋ณ ๊ฒ์์ ๋ฐ๋ณต์ ๊ฐ์ ๋๋ "์๋ค๋ก ์ต์ ํ"์ ๋ํ ์ด์ผ๊ธฐ .์ผ๋ฐํ ๋ฒ์ ์ฌ๋ฌ ํค๋ก ์ ๋ ฌ๋ ์ ํ (const / NULL ์๋ฟ๋ง ์๋๋ผ) ๊ธฐ์ฌ์์ ๋ ผ์๋ฉ๋๋ค.
SQL HowTo: ์ฟผ๋ฆฌ์์ ์ง์ while ๋ฃจํ ์์ฑ ๋๋ "๊ธฐ๋ณธ XNUMX๋ฐฉํฅ" .
#4: ์ฐ๋ฆฌ๋ ๋๋ฌด ๋ง์ด ์ฝ์ต๋๋ค.
์ธ์
์ผ๋ฐ์ ์ผ๋ก ๊ธฐ์กด ์์ฒญ์ "๋ค๋ฅธ ํํฐ๋ฅผ ์ถ๊ฐ"ํ๋ ค๋ ๊ฒฝ์ฐ์ ๋ฐ์ํฉ๋๋ค.
"๊ทธ๋ฆฌ๊ณ ๋น์ ์ ๊ฐ์ ๊ฒ์ ๊ฐ์ง๊ณ ์์ง ์์ง๋ง ์ง์ฃผ ๋ฒํผ์ ์ด๋จธ๋์ ํจ๊ป?ยป ์ํ '๋ค์ด์๋ชฌ๋ ํธ๋'
์๋ฅผ ๋ค์ด ์์ ์์ ์ ์์ ํ๋ฉด ๋ชฉ์ ์ ๊ด๊ณ์์ด ์ฒ๋ฆฌ๋ฅผ ์ํด ์ฒ์ 20๊ฐ์ ๊ฐ์ฅ ์ค๋๋ "์ค์" ์์ฒญ์ด ํ์๋ฉ๋๋ค.
์๋ณ ๋ฐฉ๋ฒ
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& 5 ร rows < RRbF -- ะพััะธะปัััะพะฒะฐะฝะพ >80% ะฟัะพัะธัะฐะฝะฝะพะณะพ
&& loops ร RRbF > 100 -- ะธ ะฟัะธ ััะพะผ ะฑะพะปััะต 100 ะทะฐะฟะธัะตะน ััะผะผะฐัะฝะพ
์ถ์ฒ
[๋] ์ ๋ฌธํ ๋ง๋ค๊ธฐ WHERE ์ ์ด ์๋ ์ธ๋ฑ์ค ๋๋ ์์ธ์ ์ถ๊ฐ ํ๋๋ฅผ ํฌํจํฉ๋๋ค.
์์ ์ ๋ํ ํํฐ๋ง ์กฐ๊ฑด์ด "์ ์ "์ธ ๊ฒฝ์ฐ ํ์ฅ์ ํฌํจํ์ง ์์ ๋ฏธ๋์ ๊ฐ ๋ชฉ๋ก - WHERE ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ค์ํ ๋ถ์ธ/์ด๊ฑฐํ ์ํ๊ฐ ์ด ๋ฒ์ฃผ์ ์ ํฉํฉ๋๋ค.
์ฌ๊ณผ์กฐ๊ฑด์ด๋ผ๋ฉด ๋ค๋ฅธ ๊ฐ์ ๊ฐ์ง ์ ์์ต๋๋ค, ์์ BitmapAnd ์ํฉ์์์ ๊ฐ์ด ์ด๋ฌํ ํ๋๋ก ์ธ๋ฑ์ค๋ฅผ ํ์ฅํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ :
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ัะฐะบัะพะฒ"
, CASE
WHEN random() < 1::real/16 THEN NULL
ELSE (random() * 100)::integer -- 100 ัะฐะทะฝัั
ะฒะฝะตัะฝะธั
ะบะปััะตะน
END fk_own
, (random() < 1::real/50) critical; -- 1:50, ััะพ ะทะฐัะฒะบะฐ "ะบัะธัะธัะฝะฐั"
CREATE INDEX ON tbl(pk);
CREATE INDEX ON tbl(fk_own, pk);
SELECT
*
FROM
tbl
WHERE
critical
ORDER BY
pk
LIMIT 20;
์์ :
CREATE INDEX ON tbl(pk)
WHERE critical; -- ะดะพะฑะฐะฒะธะปะธ "ััะฐัะธัะฝะพะต" ััะปะพะฒะธะต ัะธะปัััะฐัะธะธ
๋ณด์๋ค์ํผ ๊ณํ์ ํํฐ๋ง์ด ์์ ํ ์ฌ๋ผ์ง๊ณ ์์ฒญ์ด 5๋ฐฐ ๋ ๋น ๋ฆ.
#5: ์คํ์ค ํ ์ด๋ธ
์ธ์
์์ ์ ์์ ์ฒ๋ฆฌ ๋๊ธฐ์ด์ ๋ง๋ค๊ธฐ ์ํ ๋ค์ํ ์๋, ํ ์ด๋ธ์์ ๋ง์ ์์ ๋ ์ฝ๋ ์ ๋ฐ์ดํธ/์ญ์ ๊ฐ ๋ง์ ์์ "์ฃฝ์" ๋ ์ฝ๋ ์ํฉ์ผ๋ก ์ด์ด์ง ๋.
์๋ณ ๋ฐฉ๋ฒ
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& loops ร (rows + RRbF) < (shared hit + shared read) ร 8
-- ะฟัะพัะธัะฐะฝะพ ะฑะพะปััะต 1KB ะฝะฐ ะบะฐะถะดัั ะทะฐะฟะธัั
&& shared hit + shared read > 64
์ถ์ฒ
์๋์ผ๋ก ์ ๊ธฐ์ ์ผ๋ก ์ํ ์ง๊ณต[์ ์ฒด] ๋๋ ์ ์ ํ๊ฒ ๋น๋ฒํ ์ฒ๋ฆฌ๋ฅผ ๋ฌ์ฑ
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ด๋ฌํ ๋ฌธ์ ๋ ๋น์ฆ๋์ค ๋ก์ง์์ ํธ์ถ๋ ๋ ์๋ชป๋ ์ฟผ๋ฆฌ ๋ ์ด์์์ผ๋ก ์ธํด ๋ฐ์ํฉ๋๋ค.
PostgreSQL ์ํฐํจํด: "์ฃฝ์" ๋ฌด๋ฆฌ์ ์ธ์ฐ๊ธฐ .๊ทธ๋ฌ๋ VACUUM FULL๋ ํญ์ ๋์์ด ๋ ์๋ ์๋ค๋ ์ ์ ์ดํดํด์ผ ํฉ๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ๊ธฐ์ฌ์ ์๊ณ ๋ฆฌ์ฆ์ ์์งํด์ผ ํฉ๋๋ค.
DBA: VACUUM์ด ํต๊ณผํ๋ฉด ํ ์ด๋ธ์ ์๋์ผ๋ก ์ ๋ฆฌํฉ๋๋ค. .
#6: ์์ธ์ "์ค๊ฐ"์์ ์ฝ๊ธฐ
์ธ์
๊ทธ๋ค์ ์กฐ๊ธ ์ฝ์ ๊ฒ ๊ฐ๊ณ ๋ชจ๋ ๊ฒ์ด ์์ธํ๋์์ผ๋ฉฐ ์ถ๊ฐ๋ก ํํฐ๋งํ์ง ์์์ง๋ง ์ฌ์ ํ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ๋ง์ ํ์ด์ง๋ฅผ ์ฝ์์ต๋๋ค.
์๋ณ ๋ฐฉ๋ฒ
-> Index [Only] Scan [Backward]
&& loops ร (rows + RRbF) < (shared hit + shared read) ร 8
-- ะฟัะพัะธัะฐะฝะพ ะฑะพะปััะต 1KB ะฝะฐ ะบะฐะถะดัั ะทะฐะฟะธัั
&& shared hit + shared read > 64
์ถ์ฒ
์ฌ์ฉ๋ ์ธ๋ฑ์ค์ ๊ตฌ์กฐ์ ์ฟผ๋ฆฌ์ ์ง์ ๋ ํค ํ๋๋ฅผ ์์ธํ ์ดํด๋ณด์ญ์์ค. ์์ธ ๋ถ๋ถ์ด ์ค์ ๋์ง ์์. ๋น์ทํ ์์ธ์ ๋ง๋ค์ด์ผ ํ ๊ฐ๋ฅ์ฑ์ด ๋์ง๋ง ์ ๋์ฌ ํ๋๊ฐ ์๊ฑฐ๋
์ :
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ัะฐะบัะพะฒ"
, (random() * 100)::integer fk_org -- 100 ัะฐะทะฝัั
ะฒะฝะตัะฝะธั
ะบะปััะตะน
, (random() * 1000)::integer fk_cli; -- 1K ัะฐะทะฝัั
ะฒะฝะตัะฝะธั
ะบะปััะตะน
CREATE INDEX ON tbl(fk_org, fk_cli); -- ะฒัะต ะฟะพััะธ ะบะฐะบ ะฒ #2
-- ัะพะปัะบะพ ะฒะพั ะพัะดะตะปัะฝัะน ะธะฝะดะตะบั ะฟะพ fk_cli ะผั ัะถะต ะฟะพััะธัะฐะปะธ ะปะธัะฝะธะผ ะธ ัะดะฐะปะธะปะธ
SELECT
*
FROM
tbl
WHERE
fk_cli = 999 -- ะฐ fk_org ะฝะต ะทะฐะดะฐะฝะพ, ั
ะพัั ััะพะธั ะฒ ะธะฝะดะตะบัะต ัะฐะฝััะต
LIMIT 20;
์์ธ ์ธก๋ฉด์์๋ ๋ชจ๋ ๊ฒ์ด ๊ด์ฐฎ์ ๊ฒ ๊ฐ์ง๋ง ์ ์ง ์์ฌ ์ค๋ฝ์ต๋๋ค. 20 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ์ฝ์ ๋๋ง๋ค 4 ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ๋นผ์ผํ๊ณ ๋ ์ฝ๋ ๋น 32KB๊ฐ ๊ตต๊ฒ ํ์๋์ง ์์ต๋๊น? ์ ๋ฐ ์์ธ ์ด๋ฆ tbl_fk_org_fk_cli_idx
์๊ฐ์ผ๋ก ์ด์ด์ง๋๋ค.
์์ :
CREATE INDEX ON tbl(fk_cli);
๊ฐ์๊ธฐ - 10๋ฐฐ ๋ ๋น ๋ฅด๊ณ 4๋ฐฐ ๋ ์ ์ ์ฝ๊ธฐ!
์ธ๋ฑ์ค์ ๋นํจ์จ์ ์ธ ์ฌ์ฉ์ ๋ํ ๋ ๋ง์ ์๋ ๊ธฐ์ฌ๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
DBA: ์ธ๋ชจ์๋ ์ธ๋ฑ์ค ์ฐพ๊ธฐ .
#7: CTE ร CTE
์ธ์
์์ฒญ ์ค "๋ฑ๋ฑํ" CTE ์ ์ ๋ค๋ฅธ ํ
์ด๋ธ์์, ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ค ์ฌ์ด์์ํ๊ธฐ๋ก ๊ฒฐ์ JOIN
.
์ฌ๋ก๋ v12 ์ดํ ๋ฒ์ ๋๋ ๋ค์๊ณผ ๊ฐ์ ์์ฒญ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. WITH MATERIALIZED
.
์๋ณ ๋ฐฉ๋ฒ
-> CTE Scan
&& loops > 10
&& loops ร (rows + RRbF) > 10000
-- ัะปะธัะบะพะผ ะฑะพะปััะพะต ะดะตะบะฐััะพะฒะพ ะฟัะพะธะทะฒะตะดะตะฝะธะต CTE
์ถ์ฒ
์์ฒญ์ ์ ์คํ๊ฒ ๋ถ์
#8: ๋์คํฌ๋ก ์ค์(์์ ์ฐ๊ธฐ)
์ธ์
๋ง์ ๋ ์ฝ๋์ ์ผํ์ฑ ์ฒ๋ฆฌ(์ ๋ ฌ ๋๋ ๊ณ ์ ํ)๋ ์ด๋ฅผ ์ํด ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ง์ง ์์ต๋๋ค.
์๋ณ ๋ฐฉ๋ฒ
-> *
&& temp written > 0
์ถ์ฒ
์ฐ์ฐ์ ์ฌ์ฉ๋๋ ๋ฉ๋ชจ๋ฆฌ์ ์์ด ํ๋ผ๋ฏธํฐ์ ์ค์ ๊ฐ์ ํฌ๊ฒ ์ด๊ณผํ์ง ์๋ ๊ฒฝ์ฐ SET [LOCAL]
ํน์ ์์ฒญ/๊ฑฐ๋์ ๋ํด.
์ :
SHOW work_mem;
-- "16MB"
SELECT
random()
FROM
generate_series(1, 1000000)
ORDER BY
1;
์์ :
SET work_mem = '128MB'; -- ะฟะตัะตะด ะฒัะฟะพะปะฝะตะฝะธะตะผ ะทะฐะฟัะพัะฐ
๋ถ๋ช ํ ์ด์ ๋ก ๋์คํฌ๊ฐ ์๋ ๋ฉ๋ชจ๋ฆฌ๋ง ์ฌ์ฉํ๋ฉด ์ฟผ๋ฆฌ๊ฐ ํจ์ฌ ๋นจ๋ผ์ง๋๋ค. ๋์์ ๋ถํ์ ์ผ๋ถ๋ HDD์์ ์ ๊ฑฐ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๋ ๊ฒ์ด ํญ์ ์๋ํ์ง ์๋๋ค๋ ๊ฒ์ ์ดํดํด์ผ ํฉ๋๋ค. ๋จ์ํ ๋ชจ๋ ์ฌ๋์๊ฒ ์ถฉ๋ถํ์ง ์์ ๊ฒ์ ๋๋ค.
#9: ๊ด๋ จ ์๋ ํต๊ณ
์ธ์
ํ ๋ฒ์ ๊ธฐ์ง์ ๋ง์ ์์ ์์ ๋ถ์์ง๋ง ๋ชฐ์ ๋ผ ์๊ฐ์ด ์์์ต๋๋ค ANALYZE
.
์๋ณ ๋ฐฉ๋ฒ
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& ratio >> 10
์ถ์ฒ
๊ฐ์ ์ง์ถ ANALYZE
.
์ด ์ํฉ์ ์ ์์ธํ ์ค๋ช ๋์ด ์์ต๋๋ค.
PostgreSQL ์ํฐํจํด: ํต๊ณ๋ ๋ชจ๋ ๊ฒ์ ํต์ฌ์ ๋๋ค. .
#10: "๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค."
์ธ์
๊ฒฝ์ ์์ฒญ์ ๊ธฐ๋ค๋ฆฌ๋ ์ ๊ธ์ด ์๊ฑฐ๋ CPU/ํ์ดํผ๋ฐ์ด์ ํ๋์จ์ด ๋ฆฌ์์ค๊ฐ ์ถฉ๋ถํ์ง ์์ต๋๋ค.
์๋ณ ๋ฐฉ๋ฒ
-> *
&& (shared hit / 8K) + (shared read / 1K) < time / 1000
-- RAM hit = 64MB/s, HDD read = 8MB/s
&& time > 100ms -- ัะธัะฐะปะธ ะผะฐะปะพ, ะฝะพ ัะปะธัะบะพะผ ะดะพะปะณะพ
์ถ์ฒ
์ธ๋ถ ์ฌ์ฉ ๊ฐ์ ์ฒด๊ณ ์ฐจ๋จ ๋๋ ๋น์ ์์ ์ธ ๋ฆฌ์์ค ์๋น๋ฅผ ์ํ ์๋ฒ. ์๋ฐฑ ๋์ ์๋ฒ์ ๋ํด ์ด ํ๋ก์ธ์ค๋ฅผ ๊ตฌ์ฑํ๋ ๋ฒ์ ์ ๋ํด ์ด๋ฏธ ์ด์ผ๊ธฐํ์ต๋๋ค.
์ถ์ฒ : habr.com