์ฃผ๋ฌธ์ ์ฐพ๋ ์ฟผ๋ฆฌ๊ฐ ๋๋ ธ๋ค. ์ธ๋ฑ์ค๋ ์ด๋ฏธ ์์๋ค.
Table of contents
Open Table of contents
๋น์ทํ ์ปฌ๋ผ์ด ์ฌ๋ฟ์ด์๋ค
ํ ์ด๋ธ์ ์ด์ด ๋ณด๋ ์ฃผ๋ฌธ์ ๊ฐ๋ฆฌํค๋ ๊ฐ์ด ๋ท์ด์๋ค.
`no` bigint ์ฃผ๋ฌธ ์ผ๋ จ๋ฒํธ
`order_no` varchar(20) ์ฃผ๋ฌธ๋ฒํธ (ํ๋ฉด์ ๋ณด์ด๋ ๊ฒ)
`channel_order_no` varchar(50) ์ฑ๋์ด ์ค ์ฃผ๋ฌธ๋ฒํธ
`payment_no` varchar(30) ๊ฒฐ์ ์ฌ ๊ฑฐ๋๋ฒํธ
๋ท ๋ค ์ฃผ๋ฌธ ํ๋๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์ํฉ๋ง๋ค ๋ค๋ฅธ ๊ฒ์ ์ฐ๋๋ฐ ์ด๋ฆ์ด ๋น์ทํด ์ด๋ ๊ฒ์ด ์กฐํ์ ์ฐ์ด๋์ง๊ฐ ์ฝ๋๋ก๋ ์ ๊ฐ๋ ธ๋ค.
CREATE INDEX ix_order_no ON orders (order_no);
์ธ๋ฑ์ค๋ order_no ์ ๊ฑธ๋ ค ์์๋๋ฐ ํ๋ฉด์ ๋ณด์ด๋ ๋ฒํธ์ด๋ ๊ทธ๊ฒ์ผ๋ก ์ฐพ์ ๊ฒ์ด๋ผ๋ ํ๋จ์ด ์์ฐ์ค๋ฝ๋ค.
์ธ๋ฑ์ค๋ฅผ ๊ฑด ์ฌ๋๋ ๊ทธ๋ ๊ฒ ๋ดค์ ํ ๋ฐ ๊ทธ ํ๋จ์ด ์ง๊ธ๋ ๋ง๋์ง๋ ๋ฐ๋ก ํ์ธํ ์ผ์ด์๋ค.
์ธ๋ฑ์ค๋ ํ ๋ฒ ๊ฑธ๋ฉด ์ ์ ๋ค์ฌ๋ค๋ณด๊ณ ๊ฑธ ๋์ ํ๋จ์ด ๊ทธ๋๋ก ๊ตณ์ด ๋ช ํด๋ฅผ ๊ฐ๋ค.
๊ทธ ์ฌ์ด์ ์กฐํํ๋ ์ชฝ์ ๊ณ์ ๋ฐ๋๊ณ ํ๋ฉด์ด ๋๊ณ ์ฐ๋์ด ๋ถ์ผ๋ฉฐ ๋ฌด์์ผ๋ก ์ฐพ๋์ง๊ฐ ๋ฌ๋ผ์ง๋ค.
์์ธ โ ์ธ๋ฑ์ค์ ๋ค๋ฅธ ์กฐํ ์ปฌ๋ผ
๋๋ฆฐ ์ฟผ๋ฆฌ๋ฅผ ๋ดค๋ค.
SELECT * FROM orders WHERE channel_order_no = ?;
channel_order_no ๋ก ์ฐพ๋๋ฐ ๊ฑฐ๊ธฐ์๋ ์ธ๋ฑ์ค๊ฐ ์์๊ณ ์ด ์กฐํ๊ฐ ํ๋ฃจ 12๋ง ๋ฒ ๋๊ณ ์์๋ค.
EXPLAIN SELECT * FROM orders WHERE channel_order_no = 'ABC123';
type: ALL rows: 4218441
type ์ด ALL ์ด๊ณ rows ๊ฐ 420๋ง์ด๋ผ ํ ๊ฑด์ ์ฐพ์ผ๋ ค๊ณ ์ ์ฒด๋ฅผ ์ฝ๊ณ ์์๋ค.
์ธ๋ฑ์ค๊ฐ ์๋๋ฐ ๋๋ฆฌ๋ฉด ๊ทธ๊ฒ์ ์ ํ๋ ๊ฒ์ด๋ค. ์กฐ๊ฑด์ ์ปฌ๋ผ๊ณผ ์ธ๋ฑ์ค์ ์ปฌ๋ผ์ด ๋ฌ๋๋ค.
์ธ๋ฑ์ค๊ฐ ์๋ค๋ ์ฌ์ค๋ง ํ์ธํ๊ณ ๋์ด๊ฐ๋ฉด ์ฌ๊ธฐ์ ๋งํ๋ค. ์ด๋ ์ปฌ๋ผ์ ๊ฑธ๋ ธ๋์ง๊น์ง ๋ด์ผ ๊ทธ๋ค์์ด ๋์จ๋ค.
๋๋ฆฌ๋ค๋ ์ ๋ณด์ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ ์ฌ์ค์ด ๋ ๋ค ๋ง์๊ณ ๋์ ์ด์ด ๋ถ์ธ ๊ฒฐ๋ก ๋ง ํ๋ ธ๋ค.
์ด๋ ๊ฒ์ผ๋ก ์ผ๋ง๋ ์ฐพ๋์ง ์ ๋ค
์ธ๋ฑ์ค๋ฅผ ๊ฑธ๊ธฐ ์ ์ ์ค์ ์ฌ์ฉ์ ์ ๋ค.
$ grep -o "WHERE [a-z_]*_no = " /var/log/mysql/slow.log | sort | uniq -c | sort -rn
122841 WHERE channel_order_no =
41022 WHERE order_no =
8820 WHERE payment_no =
channel_order_no ๊ฐ order_no ๋ณด๋ค ์ธ ๋ฐฐ ๋ง์ด ์ฐ์๊ณ ์๋ ์ธ๋ฑ์ค๊ฐ ์ค์ ์ฐ๋ ์ปฌ๋ผ๊ณผ ๋ฌ๋๋ค.
์ฝ๋๋ก ์ง์ํ๋ ๊ฒ๊ณผ ๋๊ฐ๋ ์กฐํ๋ฅผ ์ธ๋ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋๋ค. ๋ฐฐ์น์ ์ฐ๋์์ ๋ถ๋ฅด๋ ๊ฒฝ๋ก๊ฐ ์์ด์๋ค.
๋ฌด์์ ์ธ๋ฑ์ค๋ฅผ ๊ฑธ์ง๋ ์ด ์ซ์๊ฐ ์ ํด ์คฌ๋ค. ์ง์์ผ๋ก ๊ฑธ์์ผ๋ฉด ๋ order_no ๋ฅผ ์๋ดค์ ๊ฒ์ด๋ค.
ํ๋จ ๊ธฐ์ค โ ๊ฐ์ ์ฑ๊ฒฉ
๊ฑธ๊ธฐ ์ ์ ๊ทธ ์ปฌ๋ผ์ ๊ฐ์ด ์ด๋ค ์ฑ๊ฒฉ์ธ์ง ๋ดค๋ค.
SELECT COUNT(*), COUNT(DISTINCT channel_order_no) FROM orders;
4,218,441 4,102,882
COUNT(DISTINCT) ๊ฐ ์ ์ฒด์ ๋น์ทํด ์ธ๋ฑ์ค๋ก ์ ๊ฐ๋ฆฐ๋ค. NULL ์ด ์ผ๋ง๋ ๋๋์ง๋ ๋ดค๋ค.
SELECT COUNT(*) FROM orders WHERE channel_order_no IS NULL;
115,559
์ง์ ์ฃผ๋ฌธ์ ์ฑ๋ ์ฃผ๋ฌธ๋ฒํธ๊ฐ ์๋๋ฐ NULL ์ด ๋ง์ผ๋ฉด ์ธ๋ฑ์ค์ ์ธ๋ชจ๊ฐ ์ค์ง๋ง 3%๋ผ ๊ด์ฐฎ์๋ค.
๊ฐ์ด ์ ๊ฐ๋ฆฌ๋ฉด ์ธ๋ฑ์ค๋ฅผ ๊ฑธ์ด๋ ํจ๊ณผ๊ฐ ์๋ค. ๊ฑฐ๋ ๋น์ฉ์ ๊ฐ์ผ๋ฏ๋ก ๊ฑธ๊ธฐ ์ ์ ์ฌ ๋ณด๋ ๊ฒ์ด ์์๋ค.
์ธ๋ฑ์ค๋ฅผ ๊ฑฐ๋ ์ผ์ ๋๋๋ฆฌ๊ธฐ ์ฌ์ ๋ณด์ฌ์ ์ผ๋จ ๊ฑธ์ด ๋ณด์๋ ์ชฝ์ผ๋ก ๊ธฐ์ธ๊ธฐ ์ฝ๋ค. 400๋ง ๊ฑด์ 8๋ถ์ด ๊ฑธ๋ฆฌ๋ ์์ ์ด๋ผ ์ค์ ๋ก๋ ๊ทธ๋ ์ง ์์๋ค.
๊ฑฐ๋ ์๊ฐ๊ณผ ์ง์ฐ๋ ์๊ฐ์ด ๋ ๋ค ๋ค์ด์ ์ฌ ๋ณด๊ณ ๊ฑฐ๋ ์ชฝ์ด ๋ ๋ฒ ์ผํ์ง ์๋ ๊ธธ์ด์๋ค.
์ฑ๋๊ณผ ๊ฐ์ด ๊ฑธ์๋ค
๊ฐ์ ์ฑ๋ ์ฃผ๋ฌธ๋ฒํธ๊ฐ ๋ค๋ฅธ ์ฑ๋์ ์์ ์ ์๋ค๋ ๊ฒ์ด ๊ฑธ๋ ธ๋ค.
SELECT channel_order_no, COUNT(DISTINCT channel) FROM orders
GROUP BY channel_order_no HAVING COUNT(DISTINCT channel) > 1 LIMIT 5;
ABC123 2
์ค์ ๋ก ๊ทธ๋ฐ ๊ฐ์ด ์์๊ณ ์ฑ๋ ์์ด ์ฐพ์ผ๋ฉด ๋ค๋ฅธ ์ฑ๋์ ์ฃผ๋ฌธ์ด ๋์จ๋ค.
CREATE INDEX ix_channel_order ON orders (channel, channel_order_no);
channel ์ ์์ ๋๊ณ ํจ๊ป ๊ฑธ์๊ณ ์กฐํํ๋ ์ชฝ ์ฝ๋๋ ๊ณ ์ณค๋ค.
$this->db->where('channel', $channel)->where('channel_order_no', $no);
์ธ๋ฑ์ค๋ฅผ ๊ฑฐ๋ ๊น์ ์กฐํ ์์ฒด๊ฐ ํ๋ ธ๋ ๊ฒ์ ์ฐพ์๋๋ฐ ๋๋ฆฌ๋ค๋ ๋ฌธ์ ๋ฅผ ๋ณด๋ฌ ๊ฐ๋ค๊ฐ ํ๋๋ฅผ ๋ ๊ฑด์ก๋ค.
๋๋ฆฐ ์กฐํ๋ฅผ ๋ค์ฌ๋ค๋ณด๋ฉด ๊ทธ ์กฐํ๊ฐ ๋ฌด์์ ์ฐพ์ผ๋ ค๋ ๊ฒ์ธ์ง๊น์ง ์ฝ๊ฒ ๋๋ค. ๊ทธ ๊ณผ์ ์์ ์กฐ๊ฑด์ด ๋ชจ์๋ ๊ฒ์ด ๋์ ๋๋ค.
์ฑ๋ฅ ์์ ์ด ์ ํ์ฑ ๋ฌธ์ ๋ฅผ ์ฐพ์ ์ฃผ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ํ์ ์ ์ฝ๋ ์ฟผ๋ฆฌ๋ฅผ ๊ทธ๋ ์ฝ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฒ์ฆ โ ์กฐํ์ ์ ๋ ฅ ์์ชฝ
๊ฑธ๊ณ ๋์ ๋ค์ ์๋ค.
EXPLAIN SELECT * FROM orders WHERE channel = 'A' AND channel_order_no = 'ABC123';
type: ref key: ix_channel_order rows: 1
์ 1.8์ด
ํ 0.002์ด
type ์ด ref ๊ฐ ๋๊ณ rows ๊ฐ 1์ด ๋๋๋ฐ ์กฐํ๋ง ๋ณด๊ณ ๋๋ด๋ฉด ํ๋จ์ด ๋ฐ์ชฝ์ด๋ค.
์ INSERT ํ๊ท 1.2ms
ํ INSERT ํ๊ท 1.4ms
์ธ๋ฑ์ค๊ฐ ๋๋ฉด ๋ฃ์ ๋ ์ผ์ด ๋์ด 0.2๋ฐ๋ฆฌ์ด ๋์๋๋ฐ ์กฐํ๊ฐ ์ค์ด๋ ๊ฒ์ ๋นํ๋ฉด ์์๋ค.
ํ์ชฝ๋ง ์ฌ๋ฉด ํ๋จ์ด ํ๋ฆฌ๊ณ ๊ฑฐ๋ ๋ฐ ๊ฑธ๋ฆฐ ์๊ฐ๋ 400๋ง ๊ฑด์ 8๋ถ์ด๋ผ ์๋ฒฝ์ ์์ ํ๋ค.
์กฐํ๊ฐ 900๋ฐฐ ๋นจ๋ผ์ก๋ค๋ ์ซ์๋ง ๋ณด๊ณ ํ๋ฉด ๋ฃ๋ ์ชฝ์ ๊ณต์ง๋ก ๋ณด์ธ๋ค. ๋ฃ๋ ์ชฝ์ด ์ผ๋ง๋ ๋๋ ค์ก๋์ง๋ฅผ ๊ฐ์ด ์ ์ด์ผ ๊ทธ ๊ฑฐ๋๊ฐ ๋ณด์ธ๋ค.
์ด๋ฒ์๋ ๊ทธ ๊ฑฐ๋๊ฐ ๋ช ๋ฐฑํ ๋จ๋ ์ชฝ์ด์์ง๋ง ์ฌ ๋ณด๊ณ ๋งํ๋ ๊ฒ๊ณผ ์ ์ฌ๊ณ ๋งํ๋ ๊ฒ์ ๋ค๋ฅด๋ค.
์ฃผ์ โ ์ ์ฐ๋ ์ธ๋ฑ์ค
๊ฑฐ๋ ๊น์ ์ ์ฐ๋ ๊ฒ๋ ๋ดค๋ค.
SELECT * FROM sys.schema_unused_indexes WHERE object_schema = 'order';
์ธ ๊ฐ๊ฐ ๋์๊ณ ํ๋๋ ์ด๋ฏธ ์์ด์ง ์ ํ๋ฉด์์ ์ฐ๋ ๊ฒ์ด์๋ค.
์ง์ฐ๊ธฐ ์ ์ ๋ฉฐ์น ๋ ๋ดค๋๋ฐ ํต๊ณ๊ฐ ์ฌ์์์ผ๋ก ์ด๊ธฐํ๋ ์ ์์ด ํ ๋ฒ ๋ณด๊ณ ํ๋จํ๋ฉด ํ๋ฆฐ๋ค.
์ธ๋ฑ์ค๋ฅผ ๊ฑฐ๋ ๊ฒ๊ณผ ์ง์ฐ๋ ๊ฒ์ ์ํ์ด ๋ค๋ฅด๋ค. ์ง์ฐ๋ ์ชฝ์ ํ๋ฆฌ๋ฉด ์กฐํ๊ฐ ์ ๋ถ ๋๋ ค์ง๋ค.
์ ๋ฆฌ
- ๋น์ทํ ์ปฌ๋ผ์ด ์ฌ๋ฟ์ด๋ฉด ์ด๋ ๊ฒ์ผ๋ก ์ฐพ๋์ง๋ฅผ ์ค์ ๋ก๊ทธ์์ ์ผ๋ค
- ์๋ ์ธ๋ฑ์ค๊ฐ ์ค์ ์ฐ๋ ์ปฌ๋ผ๊ณผ ๋ค๋ฅผ ์ ์๋ค
- ์ฝ๋๋ก ์ง์ํ๋ฉด ๋ฐฐ์น์ ์ฐ๋์์ ๋ถ๋ฅด๋ ๊ฒฝ๋ก๊ฐ ๋น ์ง๋ค
- ๊ฑธ๊ธฐ ์ ์ ๊ฐ์ด ์ ๊ฐ๋ฆฌ๋์ง์
NULL๋น์ค์ ๋ณธ๋ค - ๊ฐ์ด ์ ๊ฐ๋ฆฌ๋ฉด ๊ฑฐ๋ ๋น์ฉ์ ๊ฐ์๋ฐ ์ป๋ ๊ฒ์ด ์๋ค
- ์กฐํ ์กฐ๊ฑด์ด ๋ถ์กฑํ ๊ฒ์ด ๊ทธ ๊ณผ์ ์์ ๋๋ฌ๋๊ธฐ๋ ํ๋ค
- ๊ฑธ๊ณ ๋์
EXPLAIN๊ณผINSERT์๊ฐ์ ๋ ๋ค ์ฐ๋ค - ํ์ชฝ๋ง ์ฌ๋ฉด ํ๋จ์ด ํ๋ฆฐ๋ค
ALTER TABLE์ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ๋ฏธ๋ฆฌ ์ฌ๊ณ ์๋น์ค ์๊ฐ์ ํผํ๋ค- ์ ์ฐ๋ ์ธ๋ฑ์ค๋ฅผ ์ง์ธ ๋๋ ํ ๋ฒ ๋ณด๊ณ ํ๋จํ์ง ์๋๋ค