์ง๋ XNUMX์์ ์ ๋ VWO ์ง์ํ์ผ๋ก๋ถํฐ ํฅ๋ฏธ๋ก์ด ๋ฒ๊ทธ ๋ณด๊ณ ์๋ฅผ ๋ฐ์์ต๋๋ค. ๋๊ท๋ชจ ๊ธฐ์ ํด๋ผ์ด์ธํธ์ ๋ํ ๋ถ์ ๋ณด๊ณ ์ ์ค ํ๋์ ๋ก๋ ์๊ฐ์ ์์ฒญ๋ ๋ณด์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ด ์ ๊ฐ ๋ด๋นํ๋ ์์ญ์ด๊ธฐ ๋๋ฌธ์ ์ฆ์ ๋ฌธ์ ํด๊ฒฐ์ ์ง์คํ์ต๋๋ค.
์ ์ฌ ์๋
๋ด๊ฐ ๋งํ๋ ๋ด์ฉ์ ๋ช ํํ๊ฒํ๊ธฐ ์ํด VWO์ ๋ํด ์กฐ๊ธ ๋ง์ ๋๋ฆฌ๊ฒ ์ต๋๋ค. ์ด๋ ์น์ฌ์ดํธ์์ ๋ค์ํ ํ๊ฒ ์บ ํ์ธ์ ์์ํ ์ ์๋ ํ๋ซํผ์ ๋๋ค. A/B ์คํ ์ํ, ๋ฐฉ๋ฌธ์ ๋ฐ ์ ํ ์ถ์ , ํ๋งค ํผ๋ ๋ถ์, ํํธ ๋งต ํ์, ๋ฐฉ๋ฌธ ๊ธฐ๋ก ์ฌ์ ๋ฑ์ด ๊ฐ๋ฅํฉ๋๋ค.
ํ์ง๋ง ํ๋ซํผ์์ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ๋ณด๊ณ ์ ๋๋ค. ์์ ๋ชจ๋ ๊ธฐ๋ฅ์ ์๋ก ์ฐ๊ฒฐ๋์ด ์์ต๋๋ค. ๊ธฐ์ ๊ณ ๊ฐ์ ๊ฒฝ์ฐ, ๋ง๋ํ ์์ ์ ๋ณด๋ ์ด๋ฅผ ๋ถ์ ํ์์ผ๋ก ์ ๊ณตํ๋ ๊ฐ๋ ฅํ ํ๋ซํผ ์์ด๋ ์ ํ ์ธ๋ชจ๊ฐ ์์ ๊ฒ์ ๋๋ค.
ํ๋ซํผ์ ์ฌ์ฉํ๋ฉด ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ์ ๋ํด ๋ฌด์์ ์ฟผ๋ฆฌ๋ฅผ ์ํํ ์ ์์ต๋๋ค. ๊ฐ๋จํ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Chrome์ ์ฌ์ฉํ๊ฑฐ๋(์ ๋ฝ์ ์์นํ๋ฉฐ iPhone์ ์ฌ์ฉํ๋) ์ฌ์ฉ์์๊ฒ <date d1>๋ถํฐ <date d2>๊น์ง 'abc.com' ํ์ด์ง์ ๋ชจ๋ ํด๋ฆญ์๋ฅผ ํ์ํฉ๋๋ค.
๋ถ์ธ ์ฐ์ฐ์์ ์ฃผ์ํ์ธ์. ํด๋ผ์ด์ธํธ๋ ์ฟผ๋ฆฌ ์ธํฐํ์ด์ค์์ ์ํ์ ์ป๊ธฐ ์ํด ์์๋ก ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋๋ฆฐ ์์ฒญ
๋ฌธ์ ์ ํด๋ผ์ด์ธํธ๋ ์ง๊ด์ ์ผ๋ก ๋น ๋ฅด๊ฒ ์๋ํด์ผ ํ๋ ์์ ์ ์ํํ๋ ค๊ณ ํ์ต๋๋ค.
"/jobs"๊ฐ ํฌํจ๋ URL์ด ์๋ ํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ ์ฌ์ฉ์์ ๋ชจ๋ ์ธ์ ๊ธฐ๋ก์ ํ์ํฉ๋๋ค.
์ด ์ฌ์ดํธ์๋ ์์ฒญ๋ ์์ ํธ๋ํฝ์ด ์์๊ณ ์ฐ๋ฆฌ๋ ์ด ์ฌ์ดํธ๋ฅผ ์ํด ๋ฐฑ๋ง ๊ฐ๊ฐ ๋๋ ๊ณ ์ URL์ ์ ์ฅํ๊ณ ์์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ค์ ๊ทธ๋ค์ ๋น์ฆ๋์ค ๋ชจ๋ธ๊ณผ ๊ด๋ จ๋ ๋งค์ฐ ๊ฐ๋จํ URL ํ ํ๋ฆฟ์ ์ฐพ๊ณ ์ถ์์ต๋๋ค.
์๋น์กฐ์ฌ
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋ค์์ ์๋์ ๋๋ฆฐ SQL ์ฟผ๋ฆฌ์ ๋๋ค.
SELECT
count(*)
FROM
acc_{account_id}.urls as recordings_urls,
acc_{account_id}.recording_data as recording_data,
acc_{account_id}.sessions as sessions
WHERE
recording_data.usp_id = sessions.usp_id
AND sessions.referrer_id = recordings_urls.id
AND ( urls && array(select id from acc_{account_id}.urls where url ILIKE '%enterprise_customer.com/jobs%')::text[] )
AND r_time > to_timestamp(1542585600)
AND r_time < to_timestamp(1545177599)
AND recording_data.duration >=5
AND recording_data.num_of_pages > 0 ;
ํ์ด๋ฐ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ณํ๋ ์๊ฐ: 1.480ms ์คํ ์๊ฐ: 1431924.650ms
์ฟผ๋ฆฌ๋ 150๋ง ํ์ ํฌ๋กค๋งํ์ต๋๋ค. ์ฟผ๋ฆฌ ํ๋๋์๋ ๋ช ๊ฐ์ง ํฅ๋ฏธ๋ก์ด ์ธ๋ถ ์ ๋ณด๊ฐ ํ์๋์์ง๋ง ๋๋ ทํ ๋ณ๋ชฉ ํ์์ ์์์ต๋๋ค.
์์ฒญ์ ๋ ์์ธํ ์ฐ๊ตฌํด ๋ณด๊ฒ ์ต๋๋ค. ๋ณด์๋ค์ํผ ๊ทธ๋ ๊ทธ๋ ์ต๋๋ค JOIN
ํ
์ด๋ธ XNUMX๊ฐ:
- ์ธ์ : ๋ธ๋ผ์ฐ์ , ์ฌ์ฉ์ ์์ด์ ํธ, ๊ตญ๊ฐ ๋ฑ ์ธ์ ์ ๋ณด๋ฅผ ํ์ํฉ๋๋ค.
- ๋ น์_๋ฐ์ดํฐ: ๊ธฐ๋ก๋ URL, ํ์ด์ง, ๋ฐฉ๋ฌธ ๊ธฐ๊ฐ
- URL์ด: ๋งค์ฐ ํฐ URL์ ์ค๋ณต์ ํผํ๊ธฐ ์ํด ๋ณ๋์ ํ ์ด๋ธ์ ์ ์ฅํฉ๋๋ค.
๋ํ ๋ชจ๋ ํ
์ด๋ธ์ ์ด๋ฏธ ๋ค์๊ณผ ๊ฐ์ด ๋ถํ ๋์ด ์์ต๋๋ค. account_id
. ์ด๋ ๊ฒ ํ๋ฉด ํนํ ํฐ ๊ณ์ ํ๋๊ฐ ๋ค๋ฅธ ๊ณ์ ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋ ์ํฉ์ด ์ ์ธ๋ฉ๋๋ค.
๋จ์๋ฅผ ์ฐพ๊ณ
์์ธํ ์กฐ์ฌํด ๋ณด๋ฉด ํน์ ์์ฒญ์ ๋ฌธ์ ๊ฐ ์์์ ์ ์ ์์ต๋๋ค. ๋ค์ ์ค์ ์์ธํ ์ดํด๋ณผ ๊ฐ์น๊ฐ ์์ต๋๋ค.
urls && array(
select id from acc_{account_id}.urls
where url ILIKE '%enterprise_customer.com/jobs%'
)::text[]
์ฒซ ๋ฒ์งธ ์๊ฐ์ ์๋ง๋ ILIKE
์ด ๋ชจ๋ ๊ธด URL์ ๋ํด(์ฐ๋ฆฌ๋ 1,4๋ง ๊ฐ ์ด์์ ์ ์ผํ ์ด ๊ณ์ ์ ๋ํด ์์ง๋ URL) ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.
ํ์ง๋ง ์๋์, ๊ทธ๊ฒ ์์ ์ด ์๋๋๋ค!
SELECT id FROM urls WHERE url ILIKE '%enterprise_customer.com/jobs%';
id
--------
...
(198661 rows)
Time: 5231.765 ms
ํ ํ๋ฆฟ ๊ฒ์ ์์ฒญ ์์ฒด์๋ 5์ด๋ฐ์ ๊ฑธ๋ฆฌ์ง ์์ต๋๋ค. ๋ฐฑ๋ง ๊ฐ์ ๊ณ ์ ํ URL์์ ํจํด์ ๊ฒ์ํ๋ ๊ฒ์ ๋ถ๋ช ํ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค.
๋ชฉ๋ก์ ๋ค์ ์ฉ์์๋ ์ฌ๋ฌ ๋ช
์
๋๋ค. JOIN
. ์๋ง๋ ๊ณผ๋ํ ์ฌ์ฉ์ผ๋ก ์ธํด ์๋๊ฐ ๋๋ ค์ก์๊น์? ๋๊ฐ JOIN
'๋ ์ฑ๋ฅ ๋ฌธ์ ์ ๊ฐ์ฅ ํ์คํ ํ๋ณด์ด์ง๋ง ์ฐ๋ฆฌ ์ฌ๋ก๊ฐ ์ ํ์ ์ธ ๊ฒ์ด๋ผ๊ณ ๋ ์๊ฐํ์ง ์์์ต๋๋ค.
analytics_db=# SELECT
count(*)
FROM
acc_{account_id}.urls as recordings_urls,
acc_{account_id}.recording_data_0 as recording_data,
acc_{account_id}.sessions_0 as sessions
WHERE
recording_data.usp_id = sessions.usp_id
AND sessions.referrer_id = recordings_urls.id
AND r_time > to_timestamp(1542585600)
AND r_time < to_timestamp(1545177599)
AND recording_data.duration >=5
AND recording_data.num_of_pages > 0 ;
count
-------
8086
(1 row)
Time: 147.851 ms
๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ๋ํ ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ๊ฐ ์๋์์ต๋๋ค. JOIN
๊ฝค ๋น ๋ฅธ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
์ฉ์์ ๋ฒ์ ์ขํ
๊ฐ๋ฅํ ์ฑ๋ฅ ํฅ์์ ๋ฌ์ฑํ๊ธฐ ์ํด ์ฟผ๋ฆฌ ๋ณ๊ฒฝ์ ์์ํ ์ค๋น๊ฐ ๋์์ต๋๋ค. ์ฐ๋ฆฌ ํ๊ณผ ๋๋ 2๊ฐ์ง ์ฃผ์ ์์ด๋์ด๋ฅผ ๊ฐ๋ฐํ์ต๋๋ค.
- ํ์ ์ฟผ๋ฆฌ URL์ EXISTS ์ฌ์ฉ: URL์ ๋ํ ํ์ ์ฟผ๋ฆฌ์ ๋ฌธ์ ๊ฐ ์๋์ง ๋ค์ ํ์ธํ๊ณ ์ถ์์ต๋๋ค. ์ด๋ฅผ ๋ฌ์ฑํ๋ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๊ฐ๋จํ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.
EXISTS
.EXISTS
์ ์กฐ๊ฑด๊ณผ ์ผ์นํ๋ ์ ์ผํ ๋ฌธ์์ด์ ์ฐพ๋ ์ฆ์ ์ข ๋ฃ๋๋ฏ๋ก ์ฑ๋ฅ์ด ํฌ๊ฒ ํฅ์๋ฉ๋๋ค.
SELECT
count(*)
FROM
acc_{account_id}.urls as recordings_urls,
acc_{account_id}.recording_data as recording_data,
acc_{account_id}.sessions as sessions
WHERE
recording_data.usp_id = sessions.usp_id
AND ( 1 = 1 )
AND sessions.referrer_id = recordings_urls.id
AND (exists(select id from acc_{account_id}.urls where url ILIKE '%enterprise_customer.com/jobs%'))
AND r_time > to_timestamp(1547585600)
AND r_time < to_timestamp(1549177599)
AND recording_data.duration >=5
AND recording_data.num_of_pages > 0 ;
count
32519
(1 row)
Time: 1636.637 ms
๊ทธ๋ ์ฃ . ๋ํ๋ ๊ฒฝ์ฐ ํ์ ์ฟผ๋ฆฌ EXISTS
, ๋ชจ๋ ๊ฒ์ ๋งค์ฐ ๋น ๋ฅด๊ฒ ๋ง๋ญ๋๋ค. ๋ค์ ๋
ผ๋ฆฌ์ ์ง๋ฌธ์ ์ ์์ฒญ์ด JOIN
-ami์ ํ์ ์ฟผ๋ฆฌ ์์ฒด๋ ๊ฐ๋ณ์ ์ผ๋ก ๋น ๋ฅด์ง๋ง ํจ๊ป ์ฌ์ฉํ๋ฉด ์์ฒญ๋๊ฒ ๋๋ฆฝ๋๋ค.
- ํ์ ์ฟผ๋ฆฌ๋ฅผ CTE๋ก ์ด๋ : ์ฟผ๋ฆฌ ์์ฒด๊ฐ ๋น ๋ฅธ ๊ฒฝ์ฐ ๋จผ์ ๋น ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๊ณ์ฐํ ๋ค์ ์ด๋ฅผ ๊ธฐ๋ณธ ์ฟผ๋ฆฌ์ ์ ๊ณตํ๋ฉด ๋ฉ๋๋ค.
WITH matching_urls AS (
select id::text from acc_{account_id}.urls where url ILIKE '%enterprise_customer.com/jobs%'
)
SELECT
count(*) FROM acc_{account_id}.urls as recordings_urls,
acc_{account_id}.recording_data as recording_data,
acc_{account_id}.sessions as sessions,
matching_urls
WHERE
recording_data.usp_id = sessions.usp_id
AND ( 1 = 1 )
AND sessions.referrer_id = recordings_urls.id
AND (urls && array(SELECT id from matching_urls)::text[])
AND r_time > to_timestamp(1542585600)
AND r_time < to_timestamp(1545107599)
AND recording_data.duration >=5
AND recording_data.num_of_pages > 0;
ํ์ง๋ง ์ฌ์ ํ ๋งค์ฐ ๋๋ ธ์ต๋๋ค.
๋ฒ์ธ ์ฐพ๊ธฐ
์ด๋ฒ์๋ ๋ด ๋์์ ์์ ์ผ ํ๋๊ฐ ๋ฒ์ฉ์๊ณ ๋๋ ๋์์์ด ๊ทธ๊ฒ์ ์์ผ๋ก ์น์๋ฒ๋ ธ์ต๋๋ค. ํ์ง๋ง ๋ ์ด์ ๋จ์ ๊ฒ์ด ์์๊ธฐ ๋๋ฌธ์ ๋๋ ๊ทธ๋
๋ฅผ ์ดํด๋ณด๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๋ด๊ฐ ์๊ธฐํ๋๊ฑฐ์ผ &&
์ด์์. ์๋
EXISTS
๋ฐฉ๊ธ ์ฑ๋ฅ์ด ํฅ์๋์์ต๋๋ค. &&
๋๋ฆฐ ์ฟผ๋ฆฌ์ ๋ชจ๋ ๋ฒ์ ์์ ์ ์ผํ๊ฒ ๋จ์ ์๋ ๊ณตํต ์์์์ต๋๋ค.
๋ณด๊ณ &&
๋ ๋ฐฐ์ด ์ฌ์ด์ ๊ณตํต ์์๋ฅผ ์ฐพ์์ผ ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
์๋ ์์ฒญ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
AND ( urls && array(select id from acc_{account_id}.urls where url ILIKE '%enterprise_customer.com/jobs%')::text[] )
์ฆ, URL์์ ํจํด ๊ฒ์์ ์ํํ ๋ค์ ๊ณตํต ๊ฒ์๋ฌผ์ด ์๋ ๋ชจ๋ URL๊ณผ์ ๊ต์ฐจ์ ์ ์ฐพ์ต๋๋ค. ์ฌ๊ธฐ์ "urls"๋ ๋ชจ๋ URL์ด ํฌํจ๋ ํ
์ด๋ธ์ ์ฐธ์กฐํ๋ ๊ฒ์ด ์๋๋ผ ํ
์ด๋ธ์ "urls" ์ด์ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ ๋ค์ ํผ๋์ค๋ฝ์ต๋๋ค. recording_data
.
์ด์ ๋ํ ์ํน์ด ์ปค์ง๋ฉด์ &&
, ์์ฑ๋ ์ฟผ๋ฆฌ ๊ณํ์์ ์ด์ ๋ํ ํ์ธ์ ์ฐพ์ผ๋ ค๊ณ ํ์ต๋๋ค. EXPLAIN ANALYZE
(์ด๋ฏธ ๊ณํ์ ์ ์ฅํด ๋์์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ์ฟผ๋ฆฌ ํ๋๋์ ๋ถํฌ๋ช
๋๋ฅผ ์ดํดํ๋ ค๊ณ ๋
ธ๋ ฅํ๋ ๊ฒ๋ณด๋ค SQL๋ก ์คํํ๋ ๊ฒ์ด ๋ ํธํฉ๋๋ค.)
Filter: ((urls && ($0)::text[]) AND (r_time > '2018-12-17 12:17:23+00'::timestamp with time zone) AND (r_time < '2018-12-18 23:59:59+00'::timestamp with time zone) AND (duration >= '5'::double precision) AND (num_of_pages > 0))
Rows Removed by Filter: 52710
์์๋ง ์ฌ๋ฌ ์ค์ ํํฐ๊ฐ์์์ต๋๋ค. &&
. ์ด๋ ์ด ์์
์ด ๋น์ฉ์ด ๋ง์ด ๋ค ๋ฟ๋ง ์๋๋ผ ์ฌ๋ฌ ๋ฒ ์ํ๋๋ค๋ ๊ฒ์ ์๋ฏธํ์ต๋๋ค.
์กฐ๊ฑด์ ๋ถ๋ฆฌํ์ฌ ํ ์คํธํ์ต๋๋ค.
SELECT 1
FROM
acc_{account_id}.urls as recordings_urls,
acc_{account_id}.recording_data_30 as recording_data_30,
acc_{account_id}.sessions_30 as sessions_30
WHERE
urls && array(select id from acc_{account_id}.urls where url ILIKE '%enterprise_customer.com/jobs%')::text[]
์ด ์ฟผ๋ฆฌ๋ ๋๋ ธ์ต๋๋ค. ์๋ํ๋ฉด JOIN
-s๋ ๋น ๋ฅด๊ณ ํ์ ์ฟผ๋ฆฌ๋ ๋น ๋ฆ
๋๋ค. ๋จ์ ์ ์ผํ ๊ฒ์ &&
์ด์์.
์ด๊ฒ์ ๋จ์ง ํต์ฌ ์์
์ผ ๋ฟ์
๋๋ค. ํจํด์ ๊ฒ์ํ๋ ค๋ฉด ํญ์ ๊ธฐ๋ณธ URL ํ
์ด๋ธ ์ ์ฒด๋ฅผ ๊ฒ์ํด์ผ ํ๋ฉฐ ํญ์ ๊ต์ฐจ์ ์ ์ฐพ์์ผ ํฉ๋๋ค. URL ๋ ์ฝ๋๋ก๋ ์ง์ ๊ฒ์ํ ์ ์์ต๋๋ค. ์๋ํ๋ฉด ์ด๋ ๋จ์ง ID๋ฅผ ์ฐธ์กฐํ๋ ๊ฒ์ผ ๋ฟ์ด๊ธฐ ๋๋ฌธ์
๋๋ค. urls
.
ํด๋ฒ์ผ๋ก ๊ฐ๋ ๊ธธ
&&
๋ ์ธํธ ๋ชจ๋ ๊ฑฐ๋ํ๊ธฐ ๋๋ฌธ์ ๋๋ฆฝ๋๋ค. ๊ต์ฒดํ๋ฉด ์์ ์ด ๋น๊ต์ ๋นจ๋ฆฌ ๋ ๊ฒ ๊ฐ์์ urls
์ { "http://google.com/", "http://wingify.com/" }
.
๋๋ ์ฌ์ฉํ์ง ์๊ณ Postgres์์ ๊ต์ฐจ์ ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์ฐพ๊ธฐ ์์ํ์ต๋๋ค. &&
, ๊ทธ๋ฌ๋ ๋ง์ ์ฑ๊ณต์ ๊ฑฐ๋์ง ๋ชปํ์ต๋๋ค.
๊ฒฐ๊ตญ ์ฐ๋ฆฌ๋ ๋ฌธ์ ๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ํด๊ฒฐํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๋ชจ๋ ๊ฒ์ ๋์๊ฒ ์ฃผ์ญ์์ค. urls
URL์ด ํจํด๊ณผ ์ผ์นํ๋ ์ค. ์ถ๊ฐ ์กฐ๊ฑด์ด ์์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
SELECT urls.url
FROM
acc_{account_id}.urls as urls,
(SELECT unnest(recording_data.urls) AS id) AS unrolled_urls
WHERE
urls.id = unrolled_urls.id AND
urls.url ILIKE '%jobs%'
๋์ ์ JOIN
๋ฐฉ๊ธ ํ์ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ ํ์ฅํ์ต๋๋ค. recording_data.urls
์กฐ๊ฑด์ ์ง์ ์ ์ฉํ ์ ์๋๋ก ๋ฐฐ์ด WHERE
.
์ฌ๊ธฐ์ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ &&
์ฃผ์ด์ง ํญ๋ชฉ์ ์ผ์นํ๋ URL์ด ํฌํจ๋์ด ์๋์ง ํ์ธํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์กฐ๊ธ๋ง ์ดํด๋ณด๋ฉด ์ด ์์
์ด ๋ฐฐ์ด์ ์์(๋๋ ํ
์ด๋ธ์ ํ)๋ฅผ ํตํด ์ด๋ํ๊ณ ์กฐ๊ฑด(์ผ์น)์ด ์ถฉ์กฑ๋๋ฉด ์ค์ง๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์๋ฌด๊ฒ๋ ์๊ฐ๋์ง ์๋์? ์, EXISTS
.
์ดํ recording_data.urls
ํ์ ์ฟผ๋ฆฌ ์ปจํ
์คํธ ์ธ๋ถ์์ ์ฐธ์กฐํ ์ ์์ต๋๋ค. ์ด๋ฐ ์ผ์ด ๋ฐ์ํ๋ฉด ์ฐ๋ฆฌ๋ ์ค๋ ์น๊ตฌ๋ก ๋์๊ฐ ์ ์์ต๋๋ค. EXISTS
ํ์ ์ฟผ๋ฆฌ๋ฅผ ๊ทธ๊ฒ์ผ๋ก ๋ํํฉ๋๋ค.
๋ชจ๋ ๊ฒ์ ์ข ํฉํ๋ฉด ์ต์ข ์ ์ผ๋ก ์ต์ ํ๋ ์ฟผ๋ฆฌ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
SELECT
count(*)
FROM
acc_{account_id}.urls as recordings_urls,
acc_{account_id}.recording_data as recording_data,
acc_{account_id}.sessions as sessions
WHERE
recording_data.usp_id = sessions.usp_id
AND ( 1 = 1 )
AND sessions.referrer_id = recordings_urls.id
AND r_time > to_timestamp(1542585600)
AND r_time < to_timestamp(1545177599)
AND recording_data.duration >=5
AND recording_data.num_of_pages > 0
AND EXISTS(
SELECT urls.url
FROM
acc_{account_id}.urls as urls,
(SELECT unnest(urls) AS rec_url_id FROM acc_{account_id}.recording_data)
AS unrolled_urls
WHERE
urls.id = unrolled_urls.rec_url_id AND
urls.url ILIKE '%enterprise_customer.com/jobs%'
);
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง ๋ฆฌ๋ํ์ Time: 1898.717 ms
์ถํํ ์๊ฐ?!?
๊ทธ๋ ๊ฒ ๋น ๋ฅด์ง๋ ์์์! ๋จผ์ ์ ํ์ฑ์ ํ์ธํด์ผํฉ๋๋ค. ๋๋ ๋งค์ฐ ์์ฌ์ค๋ฌ์ ๋ค. EXISTS
๋ ์ผ์ฐ ์๋ฃ๋๋๋ก ๋
ผ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ๋ฏ๋ก ์ต์ ํ๋ฉ๋๋ค. ์์ฒญ์ ๋ช
ํํ์ง ์์ ์ค๋ฅ๋ฅผ ์ถ๊ฐํ์ง ์์๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
๊ฐ๋จํ ํ
์คํธ๋ฅผ ์คํํ๋ ๊ฒ์ด ์์ต๋๋ค. count(*)
๋ค์ํ ๋ฐ์ดํฐ ์ธํธ์ ๋ํ ๋๋ฆฌ๊ณ ๋น ๋ฅธ ์ฟผ๋ฆฌ ๋ชจ๋์ ์ ์ฉ๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ฐ์ดํฐ์ ์์ ํ์ ์งํฉ์ ๋ํด ๋ชจ๋ ๊ฒฐ๊ณผ๊ฐ ์ฌ๋ฐ๋ฅธ์ง ์๋์ผ๋ก ํ์ธํ์ต๋๋ค.
๋ชจ๋ ํ ์คํธ์์๋ ์ง์์ ์ผ๋ก ๊ธ์ ์ ์ธ ๊ฒฐ๊ณผ๊ฐ ๋์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๋ชจ๋ ๊ฒ์ ๊ณ ์ณค์ต๋๋ค!
๊ตํ
์ด ์ด์ผ๊ธฐ์์ ๋ฐฐ์ธ ์ ์๋ ๊ตํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์ฟผ๋ฆฌ ๊ณํ์ ์ ์ฒด ๋ด์ฉ์ ์๋ ค์ฃผ์ง๋ ์์ง๋ง ๋จ์๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
- ์ฃผ์ ์ฉ์์๊ฐ ํญ์ ์ค์ ๋ฒ์ธ์ ์๋๋๋ค.
- ๋๋ฆฐ ์ฟผ๋ฆฌ๋ฅผ ๋ถ์ํ์ฌ ๋ณ๋ชฉ ํ์์ ๊ฒฉ๋ฆฌํ ์ ์์ต๋๋ค.
- ๋ชจ๋ ์ต์ ํ๊ฐ ๋ณธ์ง์ ์ผ๋ก ํ์์ ์ธ ๊ฒ์ ์๋๋๋ค.
- ์ฌ์ฉ
EXIST
, ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์์ฐ์ฑ์ด ํฌ๊ฒ ํฅ์๋ ์ ์์ต๋๋ค.
์ถ๋ ฅ
์ฟผ๋ฆฌ ์๊ฐ์ด ~24๋ถ์์ 2์ด๋ก ๋จ์ถ๋์์ต๋๋ค. ์ฑ๋ฅ์ด ์๋นํ ํฅ์๋์์ต๋๋ค! ์ด ๊ธ์ด ํฌ๊ฒ ๋์์์๋ ๋ถ๊ตฌํ๊ณ ์ฐ๋ฆฌ๊ฐ ํ๋ ๋ชจ๋ ์คํ์ ํ๋ฃจ๋ง์ ์ด๋ฃจ์ด์ก๊ณ , ์ต์ ํ์ ํ ์คํธ์ 1,5~2์๊ฐ ์ ๋ ์์๋ ๊ฒ์ผ๋ก ์ถ์ ๋ฉ๋๋ค.
SQL์ ๋๋ ค์ํ์ง ์๋๋ค๋ฉด ํ๋ฅญํ ์ธ์ด์ด์ง๋ง, ๋ฐฐ์ฐ๊ณ ์ฌ์ฉํด ๋ณด์ญ์์ค. SQL ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ๋ฐฉ๋ฒ, ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ฟผ๋ฆฌ ๊ณํ์ ์์ฑํ๋ ๋ฐฉ๋ฒ, ์ธ๋ฑ์ค ์๋ ๋ฐฉ๋ฒ ๋ฐ ์ฒ๋ฆฌ ์ค์ธ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ฅผ ์ ์ดํดํ๋ฉด ์ฟผ๋ฆฌ๋ฅผ ๋งค์ฐ ์ฑ๊ณต์ ์ผ๋ก ์ต์ ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ณ์ํด์ ๋ค์ํ ์ ๊ทผ ๋ฐฉ์์ ์๋ํ๊ณ ์ฒ์ฒํ ๋ฌธ์ ๋ฅผ ๋ถ์ํ์ฌ ๋ณ๋ชฉ ํ์์ ์ฐพ๋ ๊ฒ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ค์ํฉ๋๋ค.
์ด์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ๋ ๊ฐ์ฅ ์ข์ ์ ์ ์ด์ ์๋ ๋ก๋๋์ง ์์๋ ๋ณด๊ณ ์๊ฐ ์ด์ ๋ ๊ฑฐ์ ์ฆ์ ๋ก๋๋๋ ๋์ ๋๊ฒ ๋์ ๋๊ฒ ์๋๊ฐ ํฅ์๋๋ค๋ ๊ฒ์ ๋๋ค.
ํน๋ณํ ๊ฐ์ฌํจ ๋ด ๋์ง๋ค ์๋ํฐ์ผ ๋ฏธ์ฌ๋ผ(Aditya Mishra)์ ๋ช
๋ น์ ๋ฐ๋ผ, ์๋ํธ์ผ ๊ฐ์ฐ๋ฃจ ะธ
์ถ์ฒ : habr.com