우규이인우윀
Eager To Learn 🌌
우규이인우윀
전체 방문자
였늘
μ–΄μ œ

λΈ”λ‘œκ·Έ 메뉴

  • 🏑 ν™ˆ
  • πŸš€ κΉƒν—ˆλΈŒ
  • β›… νƒœκ·Έ ν΄λΌμš°λ“œ
  • λΆ„λ₯˜ 전체보기 (217)
    • πŸ‘¨πŸ»‍πŸ’» PS (170)
      • JAVA (82)
      • MYSQL (1)
      • Docker (2)
      • PYTHON (24)
      • LeetCode 150 (39)
      • Algorithm 기법 (1)
      • 바킹독 (21)
    • λΈ”λ‘œκ·Έ 이사 (0)
    • Error (1)
    • CS (15)
      • DataBase (2)
      • OS (7)
      • Network (1)
      • Spring (1)
      • 자료ꡬ쑰 (3)
      • Java (1)
    • Learned (7)
      • Spring (7)
    • κ°œλ°œμ„œμ  (15)
      • 가상 λ©΄μ ‘ μ‚¬λ‘€λ‘œ λ°°μš°λŠ” λŒ€κ·œλͺ¨ μ‹œμŠ€ν…œ 섀계 기초 (1)
      • 였브젝트 - 쑰영호 (7)
      • μΉœμ ˆν•œ SQL νŠœλ‹ (7)
    • 회고 (2)
hELLO Β· Designed By μ •μƒμš°.
우규이인우윀

Eager To Learn 🌌

CS/DataBase

MySQL μ˜΅ν‹°λ§ˆμ΄μ €

2023. 8. 4. 13:48

MySQL μ„œλ²„λ‘œ μš”μ²­λœ μΏΌλ¦¬λŠ” κ²°κ³ΌλŠ” λ™μΌν•˜μ§€λ§Œ κ·Έ κ²°κ³Όλ₯Ό λ§Œλ“€μ–΄ λ‚΄λŠ” 방법은 맀우 λ‹€μ–‘ν•˜λ‹€.

 

λ‹€μ–‘ν•œ 방법 쀑, κ°€μž₯ 졜적이고 μ΅œμ†Œμ˜ λΉ„μš©μ΄ μ†Œλͺ¨λ˜λŠ” 방법을 μ„ νƒν•˜λŠ” μž‘μ—…μ„ μ˜΅ν‹°λ§ˆμ΄μ €κ°€ λ‹΄λ‹Ήν•œλ‹€.

 

MySQL μ˜΅ν‹°λ§ˆμ΄μ €λŠ” 쿼리λ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ μ—¬λŸ¬ κ°€μ§€ κ°€λŠ₯ν•œ 방법을 λ§Œλ“€κ³ , 각 λ‹¨μœ„ μž‘μ—…μ˜ λΉ„μš© 정보와 λŒ€μƒ ν…Œμ΄λΈ”μ˜ 예츑된 톡계 정보λ₯Ό μ΄μš©ν•΄ μ‹€ν–‰ κ³„νšλ³„ λΉ„μš©μ„ μ‚°μΆœν•œλ‹€.

 

μ‚°μΆœλœ λΉ„μš©μ„ λ°”νƒ•μœΌλ‘œ, λΉ„μš©μ΄ μ΅œμ†Œλ‘œ μ†Œμš”λ˜λŠ” 처리 방식을 μ„ νƒν•˜λŠ” πŸ’‘ λΉ„μš© 기반 μ˜΅ν‹°λ§ˆμ΄μ € 이닀.

μ˜΅ν‹°λ§ˆμ΄μ €κ°€ λ§Œλ“€μ–΄ λ‚΄λŠ” μ‹€ν–‰ κ³„νšμ„ 이해할 수 μžˆμ–΄μ•Ό μ‹€ν–‰ κ³„νšμ˜ λΆˆν•©λ¦¬ν•œ 뢀뢄을 μ°Ύμ•„λ‚΄κ³ , 더 μ΅œμ ν™”λœ λ°©λ²•μœΌλ‘œ μœ λ„ν•  수 μžˆλ‹€.

 

데이터 처리

 

πŸ“Œ ν’€ ν…Œμ΄λΈ” μŠ€μΊ”κ³Ό ν’€ 인덱슀 μŠ€μΊ”

 

ν’€ ν…Œμ΄λΈ” μŠ€μΊ”μ€ 인덱슀λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  ν…Œμ΄λΈ”μ˜ λͺ¨λ“  λ ˆμ½”λ“œλ₯Ό μ½λŠ” 것이닀.

 

ν’€ 인덱슀 μŠ€μΊ”μ€, 말 κ·ΈλŒ€λ‘œ 인덱슀둜 μ„€μ •λœ μΉΌλŸΌμ„ κΈ°μ€€μœΌλ‘œ 인덱싱 된 λͺ¨λ“  λ ˆμ½”λ“œλ₯Ό μ½λŠ” 것이닀.

 

 

🚨 인덱슀λ₯Ό μ΄μš©ν•  수 μ—†λŠ” 쑰건문이 μžˆκ±°λ‚˜ ν…Œμ΄λΈ” λ ˆμ½”λ“œ 전체 κ±΄μˆ˜κ°€ λ„ˆλ¬΄ μž‘μ•„μ„œ 인덱슀λ₯Ό 톡해 μ½λŠ” 것이 λΉ„νš¨μœ¨μ μ΄λΌκ³  νŒλ‹¨λ˜λŠ” 경우 ν…Œμ΄λΈ” ν’€ μŠ€μΊ”μ„ μ‚¬μš©ν•œλ‹€.

 

πŸ’‘ MySQL InnoDB λŠ” νŠΉμ • ν…Œμ΄λΈ”μ˜ μ—°μ†λœ 데이터 νŽ˜μ΄μ§€κ°€ 읽히면, μš”μ²­μ΄ 였기 전에 νŽ˜μ΄μ§€λ₯Ό 버퍼에 μ €μž₯(λ¦¬λ“œ μ–΄ν—€λ“œ : Read Ahead)해두어 μ„±λŠ₯을 ν–₯μƒμ‹œν‚¨λ‹€.

 

innodb_read_ahead_threshold μ‹œμŠ€ν…œ λ³€μˆ˜λ₯Ό μ΄μš©ν•΄, λ³€μˆ˜μ— μ„€μ •λœ 개수만큼 μ—°μ†λœ νŽ˜μ΄μ§€κ°€ 읽히면 λ¦¬λ“œ μ–΄ν—€λ“œλ₯Ό μ‹œμž‘ν•  수 μžˆλ„λ‘ μž„κ³„κ°’μ„ μ„€μ •ν•  수 μžˆλ‹€.

 

 

πŸ“Œ 병렬 처리

 

MySQL 8.0은 innodb_parallel_read_threads μ‹œμŠ€ν…œ λ³€μˆ˜λ₯Ό μ΄μš©ν•΄ ν•˜λ‚˜μ˜ 쿼리λ₯Ό μ΅œλŒ€ λͺ‡κ°œμ˜ μŠ€λ ˆλ“œλ₯Ό μ΄μš©ν•΄ μ²˜λ¦¬ν• μ§€ μ„€μ •ν•  수 μžˆλ‹€.

 

πŸ’‘ μ•„λ¬΄λŸ° WHERE 쑰건 없이 λ‹¨μˆœνžˆ ν…Œμ΄λΈ”μ˜ 전체 건수λ₯Ό κ°€μ Έμ˜€λŠ” 쿼리만, ν•˜λ‚˜μ˜ 쿼리λ₯Ό λ³‘λ ¬λ‘œ μ²˜λ¦¬ν•  수 μžˆλ‹€.

 

 

πŸ“Œ ORDER BY 처리

 

λ ˆμ½”λ“œλ₯Ό 1~2건 κ°€μ Έμ˜€λŠ” 쿼리λ₯Ό μ œμ™Έν•˜λ©΄ λŒ€λΆ€λΆ„μ˜ SELECT μΏΌλ¦¬μ—μ„œ 정렬은 ν•„μˆ˜μ μœΌλ‘œ μ‚¬μš©λœλ‹€.

 

 

μ†ŒνŠΈ 버퍼

MySQL이 정렬을 μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ λ³„λ„λ‘œ 할당받은 곡간을 μ†ŒνŠΈ 버퍼라고 ν•œλ‹€.

 

λ²„νΌμ˜ ν¬κΈ°λŠ” λ ˆμ½”λ“œμ˜ 크기에 따라 κ°€λ³€μ μœΌλ‘œ μ¦κ°€ν•˜κ³ , μ΅œλŒ€ μ‚¬μš© κ°„μœΌν•œ μ†ŒνŠΈ λ²„νΌμ˜ 곡간은 sort_buffer_size λΌλŠ” μ‹œμŠ€ν…œ λ³€μˆ˜λ‘œ μ„€μ •ν•  수 μžˆλ‹€.

 

🚨 λ§Œμ•½ μ •λ ¬ν•΄μ•Όν•  λ ˆμ½”λ“œμ˜ κ±΄μˆ˜κ°€ μ†ŒνŠΈ λ²„νΌλ‘œ ν• λ‹Ήλœ 곡간보닀 큰 경우 λ¬Έμ œκ°€ 될 수 μžˆλ‹€.

 

μ†ŒνŠΈ 버퍼에 담을 수 μžˆλŠ” 만큼 κ°€μ Έμ™€μ„œ 정렬을 μˆ˜ν–‰ν•œ λ’€, μž„μ‹œλ‘œ λ””μŠ€ν¬μ— 기둝해두고

 

λ‹€μŒ λ ˆμ½”λ“œλ₯Ό κ°€μ Έμ™€μ„œ 정렬을 μˆ˜ν–‰ν•˜κ³  λ””μŠ€ν¬μ— κΈ°λ‘ν•˜λŠ” μž‘μ—…μ„ λ°˜λ³΅ν•˜κ²Œ λœλ‹€.

 

이 μž‘μ—…μ΄ μž¦μ•„μ§ˆ 수둝 μ„±λŠ₯이 λ–¨μ–΄μ§€κ³ , κ·Έλ ‡λ‹€κ³  μ†ŒνŠΈ λ²„νΌμ˜ 크기λ₯Ό ν‚€μš°λ©΄ 큰 λ©”λͺ¨λ¦¬ ν• λ‹Ή λ•Œλ¬Έμ— μ„±λŠ₯이 λ–¨μ–΄μ§ˆ 수 μžˆλ‹€.

 

 

μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜

 

λ ˆμ½”λ“œλ₯Ό μ •λ ¬ν•  λ•Œ, λ ˆμ½”λ“œ 전체λ₯Ό μ†ŒνŠΈ 버퍼에 담을지 λ˜λŠ” μ •λ ¬ κΈ°μ€€ 칼럼만 μ†ŒνŠΈ 버퍼에 담을지에 따라 λ‚˜λˆŒ 수 μžˆλ‹€.

 

-- // μ˜΅ν‹°λ§ˆμ΄μ € 트레이슀 ν™œμ„±ν™”
SET OPTIMIZER_TRACE = "enabled=on", END_MARKERS_IN_JSON=on;

SET OPTIMIZER_TRACE_MAX_MEM_SIZE=1000000;

 

μœ„ ꡬ문으둜 μ˜΅ν‹°λ§ˆμ΄μ € 트레이슀λ₯Ό ν™œμ„±ν™” μ‹œν‚€κ³  쿼리λ₯Ό μ‹€ν–‰ν•œ λ’€

 

SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE \G

 

μœ„ ꡬ문으둜 트레이슀 λ‚΄μš©μ„ 확인해보면

 

sort_mode ν•„λ“œλ‘œ μ •λ ¬ 방식을 확인할 수 μžˆλ‹€.

 

<sort_key , rowid > : μ •λ ¬ 킀와 λ ˆμ½”λ“œμ˜ 둜우 아이디(Row ID)만 κ°€μ Έμ™€μ„œ μ •λ ¬ν•˜λŠ” 방식

<sort_key , additional_fields > : μ •λ ¬ 킀와 λ ˆμ½”λ“œ 전체λ₯Ό κ°€μ Έμ™€μ„œ μ •λ ¬ν•˜λŠ” 방식 (λ ˆμ½”λ“œ μΉΌλŸΌλ“€μ€ κ³ μ • μ‚¬μ΄μ¦ˆλ‘œ λ©”λͺ¨λ¦¬ μ €μž₯)

<sort_key , packed_additional_fields> : μ •λ ¬ 킀와 λ ˆμ½”λ“œ 전체λ₯Ό κ°€μ Έμ™€μ„œ μ •λ ¬ν•˜λŠ” 방식 (λ ˆμ½”λ“œ μΉΌλŸΌλ“€μ€ κ°€λ³€ μ‚¬μ΄μ¦ˆλ‘œ λ©”λͺ¨λ¦¬ μ €μž₯)

 

MySQL 5.7 버전 λΆ€ν„°λŠ” λ©”λͺ¨λ¦¬ κ³΅κ°„μ˜ 효율적인 μ‚¬μš©μ„ μœ„ν•΄ 3번째 방식을 μ‚¬μš©ν•œλ‹€κ³  ν•œλ‹€.

 

πŸ’‘λ ˆμ½”λ“œ 전체λ₯Ό κ°€μ Έμ™€μ„œ μ •λ ¬ν•˜λŠ” 방식은 λ§Žμ€ μ†ŒνŠΈ 버퍼 곡간이 ν•„μš”ν•˜μ§€λ§Œ ν…Œμ΄λΈ”μ„ 2번 읽을 ν•„μš”κ°€ μ—†κ³ 

 

Row ID만 κ°€μ Έμ™€μ„œ μ •λ ¬ν•˜λŠ” 방식은 μ†ŒνŠΈ λ²„νΌμ˜ ν¬κΈ°λŠ” 적게 μ‚¬μš©ν•  수 μžˆμ§€λ§Œ λ‹€λ₯Έ μΉΌλŸΌμ„ κ°€μ Έμ˜€κΈ° μœ„ν•΄ μ •λ ¬λœ ROW ID 둜 ν…Œμ΄λΈ”μ„ ν•œλ²ˆ 더 읽어야 ν•œλ‹€.

 

λ”°λΌμ„œ, λ ˆμ½”λ“œμ˜ ν¬κΈ°λ‚˜ κ±΄μˆ˜κ°€ μž‘μ„ 경우 λ ˆμ½”λ“œ 전체λ₯Ό κ°€μ Έμ˜€λŠ” 것이 μ„±λŠ₯이 μ’‹λ‹€.

 

 

    'CS/DataBase' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
    • Index(인덱슀)에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž
    우규이인우윀
    우규이인우윀
    개발자 κΏˆλ‚˜λ¬΄

    ν‹°μŠ€ν† λ¦¬νˆ΄λ°”