์ ๊ตญ ์์
์ ์ ์์ฒ๋ช
์ ๊ด๋ฆฌ์๊ฐ ๊ธฐ๋ก์ ๋ณด์ ํ๊ณ ์์ต๋๋ค.
๋ฐ๋ผ์ ๊ฐ์ฅ ๋ง์ด ๋ก๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค ํ๋์ธ ์ฐ๋ฆฌ ์์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ "๋ฌด๊ฑฐ์ด" ์ฟผ๋ฆฌ๋ฅผ ๋ค์ ํ ๋ฒ ๋ถ์ํ๋ ๊ฒ์ ๋๋ผ์ด ์ผ์ด ์๋๋๋ค.
๊ฒ๋ค๊ฐ ์ถ๊ฐ ์กฐ์ฌ๋ฅผ ํตํด ํฅ๋ฏธ๋ก์ด ์ฌ๋ก๊ฐ ๋ฐํ์ก์ต๋๋ค. ์ฒซ ๋ฒ์งธ ์ต์ ํ ํ ์ฑ๋ฅ ์ ํ ์ฌ๋ฌ ํ์ด ์์ฐจ์ ์ผ๋ก ๊ฐ์ ํ์ฌ ์์ฒญํ์ผ๋ฉฐ, ๊ฐ ํ์ ์ต์ ์ ์๋๋ฅผ ๊ฐ์ง๊ณ ๋ง ํ๋ํ์ต๋๋ค.
0: ์ฌ์ฉ์๊ฐ ์ํ๋ ๊ฒ์ด ๋ฌด์์ด์๋์?
[KDPV
์ฌ์ฉ์๊ฐ ์ด๋ฆ์ผ๋ก "๋น ๋ฅธ" ๊ฒ์์ ๋งํ ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฌด์์ ์๋ฏธํฉ๋๊น? ๋ค์๊ณผ ๊ฐ์ ํ์ ๋ฌธ์์ด์ ๋ํ "์ ์งํ" ๊ฒ์์ ๊ฑฐ์ ๋ฐ์ํ์ง ์์ต๋๋ค. ... LIKE '%ัะพะทะฐ%'
- ๊ฒฐ๊ณผ์๋ ๋ค์๋ฟ๋ง ์๋๋ผ 'ะ ะพะทะฐะปะธั'
ะธ 'ะะฐะณะฐะทะธะฝ ะ ะพะทะฐ'
ํ์ง๋ง 'ะัะพะทะฐ'
์ฌ์ง์ด 'ะะพะผ ะะตะดะฐ ะะพัะพะทะฐ'
.
์ฌ์ฉ์๋ ์ผ์์ ์ธ ์์ค์์ ๊ทํ๊ฐ ๊ทธ์๊ฒ ๋ค์์ ์ ๊ณตํ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. ๋จ์ด ์์์ผ๋ก ๊ฒ์ ์ ๋ชฉ์ ๋ ๊ด๋ จ์ฑ์ด ๋์์ง๋๋ก ํ์ธ์. ๋ค์์ผ๋ก ์์ ์
๋ ฅํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋น์ ์ ๊ทธ๊ฒ์ ํ ๊ฒ์
๋๋ค ๊ฑฐ์ ์ฆ์ - ํ๊ฐ ์
๋ ฅ์ฉ.
1: ์์ ์ ์ ํํ๋ค
๊ทธ๋ฆฌ๊ณ ๋์ฑ์ด ์ฌ๋์ ํน๋ณํ ์
๋ ฅํ์ง ์์ ๊ฒ์
๋๋ค 'ัะพะท ะผะฐะณะฐะท'
, ๋ฐ๋ผ์ ๊ฐ ๋จ์ด๋ฅผ ์ ๋์ด๋ก ๊ฒ์ํด์ผ ํฉ๋๋ค. ์๋์, ์ด์ ๋จ์ด๋ฅผ ์๋์ ์ผ๋ก "๊ณผ์ ์ง์ "ํ๋ ๊ฒ๋ณด๋ค ์ฌ์ฉ์๊ฐ ๋ง์ง๋ง ๋จ์ด์ ๋ํ ๋น ๋ฅธ ํํธ์ ์๋ตํ๋ ๊ฒ์ด ํจ์ฌ ์ฝ์ต๋๋ค. ๊ฒ์ ์์ง์ด ์ด๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง ์ดํด๋ณด์ธ์.
์ผ๋ฐ์ ์ผ๋ก, ๋ฐ๋ฅด๊ฒ ๋ฌธ์ ์ ๋ํ ์๊ตฌ ์ฌํญ์ ๊ณต์ํํ๋ ๊ฒ์ ์๋ฃจ์
์ ์ ๋ฐ ์ด์์
๋๋ค. ๋๋ก๋ ์ ์คํ ์ฌ์ฉ ์ฌ๋ก ๋ถ์
์ถ์ ๊ฐ๋ฐ์๋ ์ด๋ค ์ผ์ ํ๋์?
1.0: ์ธ๋ถ ๊ฒ์ ์์ง
์, ๊ฒ์์ด ์ด๋ ต๋ค. ์๋ฌด๊ฒ๋ ํ๊ณ ์ถ์ง ์๋ค. ๋ฐ๋ธ์ต์ค์ ๋งก๊ธฐ์! ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ๋ถ์ ๊ฒ์ ์์ง(Sphinx, ElasticSearch ๋ฑ)์ ๋ฐฐํฌํ๋๋ก ํ์ธ์.
๋๊ธฐํ ๋ฐ ๋ณ๊ฒฝ ์๋ ์ธก๋ฉด์์ ๋
ธ๋ ์ง์ฝ์ ์ด์ง๋ง ์์
์ต์
์
๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ์๋ ํด๋น ๊ณ์ ๋ฐ์ดํฐ์ ํ๋ ์์ํฌ ๋ด์์๋ง ๊ฐ ๊ณ ๊ฐ์ ๋ํด ๊ฒ์์ด ์ํ๋๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ์ ๋ณ๋์ฑ์ ์๋นํ ๋์ต๋๋ค. ๊ด๋ฆฌ์๊ฐ ์ด์ ์นด๋๋ฅผ ์
๋ ฅํ๋ค๋ฉด 'ะะฐะณะฐะทะธะฝ ะ ะพะทะฐ'
, 5-10์ด ํ์ ๊ทธ๋ ์์ ์ ์ด๋ฉ์ผ์ ํ์ํ๋ ๊ฒ์ ์์๊ณ ๊ทธ๊ฒ์ ์ฐพ์ ์์ ํ๊ณ ์ถ๋ค๋ ๊ฒ์ ์ด๋ฏธ ๊ธฐ์ตํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก - ํ์ "๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ง์ " ๊ฒ์. ๋คํ์ค๋ฝ๊ฒ๋ PostgreSQL์ ์ฌ์ฉํ๋ฉด ์ด๋ฅผ ์ํํ ์ ์์ผ๋ฉฐ ๋จ์ง ํ๋์ ์ต์ ์ด ์๋๋ผ ์ด์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1.1: "์ ์งํ" ํ์ ๋ฌธ์์ด
์ฐ๋ฆฌ๋ "ํ์ ๋ฌธ์์ด"์ด๋ผ๋ ๋จ์ด๋ฅผ ๊ณ ์ํฉ๋๋ค. ํ์ง๋ง ํ์ ๋ฌธ์์ด(์ฌ์ง์ด ์ ๊ท ํํ์์ผ๋ก๋!)์ ์ฌ์ฉํ ์์ธ ๊ฒ์์๋ ํ์ํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
๋ชจ๋ธ์ ๋จ์ํํ๊ธฐ ์ํด ๋ค์ ํ๋ ์ดํธ๋ฅผ ์ฌ์ฉํด ๋ณด๊ฒ ์ต๋๋ค.
CREATE TABLE firms(
id
serial
PRIMARY KEY
, name
text
);
์ฐ๋ฆฌ๋ ์ค์ ์กฐ์ง์ ๋ํ 7.8๋ง ๊ฐ์ ๊ธฐ๋ก์ ์ ๋ก๋ํ๊ณ ์์ธ์ ์์ฑํฉ๋๋ค.
CREATE EXTENSION pg_trgm;
CREATE INDEX ON firms USING gin(lower(name) gin_trgm_ops);
ํ๊ฐ ๊ฒ์์ ์ํด ์ฒ์ 10๊ฐ์ ๋ ์ฝ๋๋ฅผ ์ฐพ์๋ณด๊ฒ ์ต๋๋ค.
SELECT
*
FROM
firms
WHERE
lower(name) ~ ('(^|s)' || 'ัะพะทะฐ')
ORDER BY
lower(name) ~ ('^' || 'ัะพะทะฐ') DESC -- ัะฝะฐัะฐะปะฐ "ะฝะฐัะธะฝะฐััะธะตัั ะฝะฐ"
, lower(name) -- ะพััะฐะปัะฝะพะต ะฟะพ ะฐะปัะฐะฒะธัั
LIMIT 10;
์, ๊ทธ๋ฐ... 26ms, 31MB 1.7๊ฐ์ ๊ฒ์๋ ํญ๋ชฉ์ ๋ํด ๋ฐ์ดํฐ ๋ฐ 10K ์ด์์ ํํฐ๋ง๋ ๋ ์ฝ๋๋ฅผ ์ฝ์ต๋๋ค. ๊ฐ์ ๋น๊ฐ ๋๋ฌด ๋๋ค์. ์ข ๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์์๊น์?
1.2: ํ ์คํธ๋ก ๊ฒ์ํ์๊ฒ ์ต๋๊น? FTS์ ๋๋ค!
์ค์ ๋ก PostgreSQL์ ๋งค์ฐ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
CREATE INDEX ON firms USING gin(to_tsvector('simple'::regconfig, lower(name)));
SELECT
*
FROM
firms
WHERE
to_tsvector('simple'::regconfig, lower(name)) @@ to_tsquery('simple', 'ัะพะทะฐ:*')
ORDER BY
lower(name) ~ ('^' || 'ัะพะทะฐ') DESC
, lower(name)
LIMIT 10;
์ฌ๊ธฐ์๋ ์ฟผ๋ฆฌ ์คํ์ ๋ณ๋ ฌํ๊ฐ ์ฝ๊ฐ ๋์์ด ๋์์ผ๋ฉฐ, ์๊ฐ์ ์ ๋ฐ์ผ๋ก ๋จ์ถํ์ต๋๋ค. 11ms. ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ์ ์ฒด์ ์ผ๋ก 1.5๋ฐฐ ๋ ์ ์ ์์ ์ฝ์ด์ผ ํ์ต๋๋ค. 20MB. ๊ทธ๋ฌ๋ ์ฌ๊ธฐ์๋ ์ฝ์ ๋ณผ๋ฅจ์ด ํด์๋ก ์บ์ ๋๋ฝ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๊ณ ๋์คํฌ์์ ์ฝ์ ๋ชจ๋ ์ถ๊ฐ ๋ฐ์ดํฐ ํ์ด์ง๊ฐ ์์ฒญ์ ๋ํ ์ ์ฌ์ ์ธ "์ ๋"์ด ๋๊ธฐ ๋๋ฌธ์ ์ ์์๋ก ์ข์ต๋๋ค.
1.3: ์์ง๋ ์ข์์?
์ด์ ์์ฒญ์ ๋๊ตฌ์๊ฒ๋ ์ข์ง๋ง ํ๋ฃจ์ ์์ญ๋ง ๋ฒ ๋น๊ฒจ์ผ๋ง ์ฌ ๊ฒ์ ๋๋ค. 2TB ๋ฐ์ดํฐ๋ฅผ ์ฝ์ต๋๋ค. ๊ฐ์ฅ ์ข์ ๊ฒฝ์ฐ๋ ๋ฉ๋ชจ๋ฆฌ์์, ์ด์ด ์ข์ง ์๋ค๋ฉด ๋์คํฌ์์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ผ ์ข ๋ ์๊ฒ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
์ฌ์ฉ์๊ฐ ๋ณด๊ณ ์ถ์ดํ๋ ๊ฒ์ ๊ธฐ์ตํ์ ์ฒซ ๋ฒ์งธ "...๋ก ์์ํ๋". ๊ทธ๋์ ์ด๊ฒ์ ๊ฐ์ฅ ์์ํ ํํ์
๋๋ค text_pattern_ops
! ๊ทธ๋ฆฌ๊ณ ์ฐพ๊ณ ์๋ ์ต๋ 10๊ฐ์ ๋ ์ฝ๋๊ฐ "์ถฉ๋ถํ์ง ์์" ๊ฒฝ์ฐ์๋ง FTS ๊ฒ์์ ์ฌ์ฉํ์ฌ ํด๋น ๋ ์ฝ๋ ์ฝ๊ธฐ๋ฅผ ์๋ฃํด์ผ ํฉ๋๋ค.
CREATE INDEX ON firms(lower(name) text_pattern_ops);
SELECT
*
FROM
firms
WHERE
lower(name) LIKE ('ัะพะทะฐ' || '%')
LIMIT 10;
์ฐ์ํ ์ฑ๋ฅ - ์ ์ฒด 0.05ms, 100KB ์กฐ๊ธ ๋์ ์ฝ๋ค! ์ฐ๋ฆฌ๋ง ์์ด๋ฒ๋ ธ์ด ์ด๋ฆ์ผ๋ก ๋ถ๋ฅํ๋ค์ฌ์ฉ์๊ฐ ๊ฒฐ๊ณผ์์ ๊ธธ์ ์์ง ์๋๋ก:
SELECT
*
FROM
firms
WHERE
lower(name) LIKE ('ัะพะทะฐ' || '%')
ORDER BY
lower(name)
LIMIT 10;
์, ๋ญ๊ฐ ๋ ์ด์ ๊ทธ๋ค์ง ์๋ฆ๋ต์ง ์์ต๋๋ค. ์์ธ์ด ์๋ ๊ฒ ๊ฐ์ง๋ง ์ ๋ ฌ์ด ์ง๋๊ฐ๋๋ค... ๋ฌผ๋ก ์ด๋ฏธ ์ด์ ์ต์ ๋ณด๋ค ๋ช ๋ฐฐ ๋ ํจ๊ณผ์ ์ด์ง๋ง...
1.4: "ํ์ผ๋ก ๋ง๋ฌด๋ฆฌ"
ํ์ง๋ง ๋ฒ์๋ณ๋ก ๊ฒ์ํ๊ณ ์ ๋ ฌ์ ์ ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ์์ธ์ด ์์ต๋๋ค. ์ผ๋ฐ Bํธ๋ฆฌ!
CREATE INDEX ON firms(lower(name));
์ด์ ๋ํ ์์ฒญ๋ง "์๋์ผ๋ก ์์ง"๋์ด์ผ ํฉ๋๋ค.
SELECT
*
FROM
firms
WHERE
lower(name) >= 'ัะพะทะฐ' AND
lower(name) <= ('ัะพะทะฐ' || chr(65535)) -- ะดะปั UTF8, ะดะปั ะพะดะฝะพะฑะฐะนัะพะฒัั
- chr(255)
ORDER BY
lower(name)
LIMIT 10;
ํ๋ฅญํจ - ์ ๋ ฌ์ด ์๋ํ๊ณ ์์ ์๋น๊ฐ "๋ฏธ์์ "์ผ๋ก ์ ์ง๋ฉ๋๋ค. "์์ํ" FTS๋ณด๋ค ์์ฒ ๋ฐฐ ๋ ํจ๊ณผ์ ์ ๋๋ค.! ๋จ์ ๊ฒ์ ์ด๋ฅผ ํ๋์ ์์ฒญ์ผ๋ก ํตํฉํ๋ ๊ฒ์ ๋๋ค.
(
SELECT
*
FROM
firms
WHERE
lower(name) >= 'ัะพะทะฐ' AND
lower(name) <= ('ัะพะทะฐ' || chr(65535)) -- ะดะปั UTF8, ะดะปั ะพะดะฝะพะฑะฐะนัะพะฒัั
ะบะพะดะธัะพะฒะพะบ - chr(255)
ORDER BY
lower(name)
LIMIT 10
)
UNION ALL
(
SELECT
*
FROM
firms
WHERE
to_tsvector('simple'::regconfig, lower(name)) @@ to_tsquery('simple', 'ัะพะทะฐ:*') AND
lower(name) NOT LIKE ('ัะพะทะฐ' || '%') -- "ะฝะฐัะธะฝะฐััะธะตัั ะฝะฐ" ะผั ัะถะต ะฝะฐัะปะธ ะฒััะต
ORDER BY
lower(name) ~ ('^' || 'ัะพะทะฐ') DESC -- ะธัะฟะพะปัะทัะตะผ ัั ะถะต ัะพััะธัะพะฒะบั, ััะพะฑั ะะ ะฟะพะนัะธ ะฟะพ btree-ะธะฝะดะตะบัั
, lower(name)
LIMIT 10
)
LIMIT 10;
๋ ๋ฒ์งธ ํ์ ์ฟผ๋ฆฌ๊ฐ ์คํ๋ฉ๋๋ค. ์ฒซ ๋ฒ์งธ ํญ๋ชฉ์ด ์์๋ณด๋ค ์ ๊ฒ ๋ฐํ๋ ๊ฒฝ์ฐ์๋ง ๋ง์ง๋ง LIMIT
์ค ์. ์ ๋ ์ด ์ฟผ๋ฆฌ ์ต์ ํ ๋ฐฉ๋ฒ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค.
๊ทธ๋ ์ต๋๋ค. ์ด์ ํ ์ด๋ธ์๋ btree์ gin์ด ๋ชจ๋ ์์ง๋ง ํต๊ณ์ ์ผ๋ก๋ ์์ฒญ์ 10% ๋ฏธ๋ง์ด ๋ ๋ฒ์งธ ๋ธ๋ก ์คํ์ ๋๋ฌํฉ๋๋ค.. ์ฆ, ์์ ์ ๋ํด ์ฌ์ ์ ์๋ ค์ง ์ผ๋ฐ์ ์ธ ์ ํ ์ฌํญ์ ํตํด ์๋ฒ ๋ฆฌ์์ค์ ์ด ์๋น๋ฅผ ๊ฑฐ์ ์ฒ ๋ฐฐ๋ ์ค์ผ ์ ์์์ต๋๋ค!
1.5*: ํ์ผ ์์ด๋ ๊ฐ๋ฅ
๋ ๋์ LIKE
์๋ชป๋ ์ ๋ ฌ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฐฉ์ง๋์์ต๋๋ค. ๊ทธ๋ฌ๋ USING ์ฐ์ฐ์๋ฅผ ์ง์ ํ์ฌ "์ฌ๋ฐ๋ฅธ ๊ฒฝ๋ก์ ์ค์ "ํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ๋ฉ๋๋ค.
ASC
. ๋ํ ์ ์ ํน์ ์ ๋ ฌ ์ฐ์ฐ์์ ์ด๋ฆ์ ์ง์ ํ ์ ์์ต๋๋ค.USING
. ์ ๋ ฌ ์ฐ์ฐ์๋ ์ผ๋ถ B-ํธ๋ฆฌ ์ฐ์ฐ์ ๊ณ์ด๋ณด๋ค ์๊ฑฐ๋ ํผ์ ์ํด์ผ ํฉ๋๋ค.ASC
์ผ๋ฐ์ ์ผ๋ก ๋๋ฑUSING <
ะธDESC
์ผ๋ฐ์ ์ผ๋ก ๋๋ฑUSING >
.
์ฐ๋ฆฌ์ ๊ฒฝ์ฐ "๋"์ ~<~
:
SELECT
*
FROM
firms
WHERE
lower(name) LIKE ('ัะพะทะฐ' || '%')
ORDER BY
lower(name) USING ~<~
LIMIT 10;
2: ์์ฒญ์ด ์ด๋ป๊ฒ ๋ณํ๋๊ฐ
์ด์ ์ฐ๋ฆฌ๋ XNUMX๊ฐ์ ๋๋ XNUMX๋ ๋์ "๋์ด๊ธฐ" ์์ฒญ์ ๋จ๊ฒจ๋๊ณ ์ผ์ผ ์ด ๋ฉ๋ชจ๋ฆฌ "ํํ" ์งํ์ ํจ๊ป ๋ค์ "์๋จ"์ ์๋ค๋ ์ฌ์ค์ ๋๋์ต๋๋ค.๋ฒํผ ๊ณต์ ์ ์ค)์์ 5.5TB -์ฆ, ์๋๋ณด๋ค ํจ์ฌ ๋ ๋ง์ต๋๋ค.
์๋์, ๋ฌผ๋ก ๋น์ฆ๋์ค๋ ์ฑ์ฅํ๊ณ ์์ ๋๋ ๋์ด๋ฌ์ต๋๋ค. ํ์ง๋ง ๊ทธ ์ ๋๋ ์๋์์ต๋๋ค! ์ด๊ฒ์ ์ฌ๊ธฐ์ ๋ญ๊ฐ ์์ํ ๊ฒ์ด ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์์ ๋ณด๊ฒ ์ต๋๋ค.
2.1: ํ์ด์ง์ ํ์
์ด๋ ์์ ์์ ๋ค๋ฅธ ๊ฐ๋ฐ ํ์ ๋์ผํ์ง๋ง ํ์ฅ๋ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ์ฌ ๋น ๋ฅธ ์ฒจ์ ๊ฒ์์์ ๋ ์ง์คํธ๋ฆฌ๋ก "์ ํ"ํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ง๋ค๊ณ ์ถ์์ต๋๋ค. ํ์ด์ง ํ์์ด ์๋ ๋ ์ง์คํธ๋ฆฌ๋ ๋ฌด์์ ๋๊น? ๋ง์น์!
( ... LIMIT <N> + 10)
UNION ALL
( ... LIMIT <N> + 10)
LIMIT 10 OFFSET <N>;
์ด์ ๊ฐ๋ฐ์๋ ์คํธ๋ ์ค ์์ด "ํ์ด์ง๋ณ" ๋ก๋ฉ์ผ๋ก ๊ฒ์ ๊ฒฐ๊ณผ ๋ ์ง์คํธ๋ฆฌ๋ฅผ ํ์ํ ์ ์๊ฒ ๋์์ต๋๋ค.
๋ฌผ๋ก ์ค์ ๋ก๋ ์ดํ์ ๋ฐ์ดํฐ ํ์ด์ง๋ง๋ค ์ ์ ๋ ๋ง์ ์์ ๋ฐ์ดํฐ๊ฐ ์ฝํ์ง๋๋ค. (์ด์ ์๊ฐ์ ๋ชจ๋ ๋ด์ฉ๊ณผ ํ์ํ "๊ผฌ๋ฆฌ"๋ฅผ ์ถ๊ฐํจ) - ์ฆ, ์ด๋ ๋ช ํํ ๋ฐํจํด์ ๋๋ค. ๊ทธ๋ฌ๋ ์ธํฐํ์ด์ค์ ์ ์ฅ๋ ํค๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ ๋ฐ๋ณต์์ ๊ฒ์์ ์์ํ๋ ๊ฒ์ด ๋ ์ ํํ ๊ฒ์ ๋๋ค.
2.2: ์ด๊ตญ์ ์ธ ๊ฒ์ ์ํด์
์ด๋ ์์ ์์ ๊ฐ๋ฐ์๋ ์ํ์ต๋๋ค. ๊ฒฐ๊ณผ ์ํ์ ๋ฐ์ดํฐ๋ก ๋ค์ํ ์ ์ฒด ์ด์ ์์ฒญ์ด CTE๋ก ์ ์ก๋ ๋ค๋ฅธ ํ ์ด๋ธ์์:
WITH q AS (
...
LIMIT <N> + 10
)
SELECT
*
, (SELECT ...) sub_query -- ะบะฐะบะพะน-ัะพ ะทะฐะฟัะพั ะบ ัะฒัะทะฐะฝะฝะพะน ัะฐะฑะปะธัะต
FROM
q
LIMIT 10 OFFSET <N>;
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ํ์ ์ฟผ๋ฆฌ๋ ๋ฐํ๋ 10๊ฐ์ ๋ ์ฝ๋์ ๋ํด์๋ง ํ๊ฐ๋๋ฏ๋ก ๋์์ง ์์ต๋๋ค.
2.3: DISTINCT๋ ๋ฌด์๋ฏธํ๊ณ ๋ฌด์๋นํฉ๋๋ค.
2์ฐจ ์๋ธ์ฟผ๋ฆฌ์์ ๊ทธ๋ฐ ์งํ ๊ณผ์ ์ด๋๊ฐ์์ ์์ด๋ฒ๋ฆฐ NOT LIKE
์กฐ๊ฑด. ์ด ์ดํ์๋ ๋ถ๋ช
ํ๋ค. UNION ALL
๋์์ค๊ธฐ ์์ํ๋ค ์ผ๋ถ ํญ๋ชฉ์ด ๋ ๋ฒ - ์ฒ์์๋ ์ค์ ์์ ๋ถ๋ถ์์ ๋ฐ๊ฒฌ๋๊ณ , ๊ทธ ๋ค์์๋ ๋ค์ - ์ด ์ค์ ์ฒซ ๋ฒ์งธ ๋จ์ด์ ์์ ๋ถ๋ถ์์ ๋ฐ๊ฒฌ๋ฉ๋๋ค. ํ๊ณ ๋ด์์ ๋ ๋ฒ์งธ ํ์ ์ฟผ๋ฆฌ์ ๋ชจ๋ ๋ ์ฝ๋๋ ์ฒซ ๋ฒ์งธ ํ์ ์ฟผ๋ฆฌ์ ๋ ์ฝ๋์ ์ผ์นํ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์๋ ์์ธ์ ์ฐพ๋ ๋์ ๋ฌด์์ ํฉ๋๊น?.. ์ง๋ฌธ์์ต๋๋ค!
- ํฌ๊ธฐ๋ฅผ ๋ ๋ฐฐ๋ก ๋๋ฆฌ๋ค ์๋ณธ ์ํ
- DISTINCT๋ฅผ ์ ์ฉํ๋ค๊ฐ ์ค์ ๋จ์ผ ์ธ์คํด์ค๋ง ์ป์ผ๋ ค๋ฉด
WITH q AS (
( ... LIMIT <2 * N> + 10)
UNION ALL
( ... LIMIT <2 * N> + 10)
LIMIT <2 * N> + 10
)
SELECT DISTINCT
*
, (SELECT ...) sub_query
FROM
q
LIMIT 10 OFFSET <N>;
์ฆ, ๊ฒฐ๊ณผ๋ ๊ฒฐ๊ตญ ๋๊ฐ๋ค๋ ๊ฒ์ด ๋ถ๋ช ํ์ง๋ง ๋ ๋ฒ์งธ CTE ํ์ ์ฟผ๋ฆฌ๋ก "๋ ์๊ฐ" ํ๋ฅ ์ด ํจ์ฌ ๋์์ก์ผ๋ฉฐ ์ด๊ฒ์ด ์์ด๋ ํ์คํ ๋ ์ฝ๊ธฐ ์ฌ์์.
๊ทธ๋ฌ๋ ์ด๊ฒ์ ๊ฐ์ฅ ์ฌํ ์ผ์ด ์๋๋๋ค. ๊ฐ๋ฐ์๊ฐ ์ ํํ๋ผ๊ณ ํด์ DISTINCT
ํน์ ๋ถ์ผ๊ฐ ์๋ ๋ชจ๋ ๋ถ์ผ๋ฅผ ๋์์ ๋์์ผ๋ก ๋ ์ฝ๋๊ฐ ์์ผ๋ฉด ํ์ ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ์ธ sub_query ํ๋๊ฐ ์๋์ผ๋ก ์ฌ๊ธฐ์ ํฌํจ๋ฉ๋๋ค. ์ด์ ์คํํ๋ ค๋ฉด DISTINCT
, ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ด๋ฏธ ์คํ๋์ด์ผ ํ์ต๋๋ค. 10๊ฐ์ ํ์ ์ฟผ๋ฆฌ๊ฐ ์๋๋ผ ๋ชจ๋ <2 * N> + 10!
2.4: ๋ฌด์๋ณด๋ค๋ ํ๋ ฅ!
๋ฐ๋ผ์ ๊ฐ๋ฐ์๋ ๊ณ์ ์ด์์ต๋๋ค. ์ฌ์ฉ์๋ ๊ฐ ํ์ "ํ์ด์ง"์์ ์ด ๋ง์ฑ์ ์ผ๋ก ๋๋ ค์ง๋ฉด์ ๋ ์ง์คํธ๋ฆฌ๋ฅผ ์ค์ํ N ๊ฐ์ผ๋ก "์กฐ์ "ํ ์ถฉ๋ถํ ์ธ๋ด์ฌ์ด ์์๊ธฐ ๋๋ฌธ์ ์ ๊ฒฝ ์ฐ์ง ์์์ต๋๋ค.
๋ค๋ฅธ ๋ถ์์ ๊ฐ๋ฐ์๋ค์ด ์์ ์ด๋ ๊ฒ ํธ๋ฆฌํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๊ณ ์ถ์ด์ง๊ธฐ ์ ๊น์ง๋ ๋ฐ๋ณต ๊ฒ์์ ์ํด - ์ฆ, ์ผ๋ถ ์ํ์์ ์กฐ๊ฐ์ ๊ฐ์ ธ์ ์ถ๊ฐ ์กฐ๊ฑด์ผ๋ก ํํฐ๋งํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ฆฐ ๋ค์ ๋ค์ ์กฐ๊ฐ(์ฐ๋ฆฌ์ ๊ฒฝ์ฐ N์ ์ฆ๊ฐ์์ผ ๋ฌ์ฑ) ๋ฑ์ ํ๋ฉด์ ์ฑ์ธ ๋๊น์ง ๊ณ์ํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ํฌํ๋ ํ๋ณธ์์๋ N์ ๊ฑฐ์ 17K ๊ฐ์ ๋๋ฌํ์ต๋๋ค., ๋จ ํ๋ฃจ ๋ง์ ์ด๋ฌํ ์์ฒญ ์ค ์ต์ 4K๊ฐ "์ฒด์ธ์ ๋ฐ๋ผ" ์คํ๋์์ต๋๋ค. ๊ทธ ์ค ๋ง์ง๋ง์ ๋๋ดํ๊ฒ ์ค์บ๋์์ต๋๋ค. ๋ฐ๋ณต๋น 1GB ๋ฉ๋ชจ๋ฆฌ...
์ ์ฒด๋ก
์ถ์ฒ : habr.com