자율주행 관련 비즈니스 도메인 분석이 필요하여 정리하였던 자료입니다.
  여기 저기에서 퍼온 내용을 모아둔 것이라 문체가 일관성없고 설명이 빈약한 경우도 있지만
  그냥 참고용으로 포스팅해봅니다.

 

용어 구분   기관 및 관련 표준
용어   국제자동차기술자협회
영문 약어   SAE
영문 Full name   Society of Automotive Engineers
설명   자율주행 관련 표준을 정의한 협회.
항공우주, 자동차 및 상용차 업계에서 종사하는 엔지니어와 관련 기술 전문가로 구성된 글로벌 협회. 평생 교육과 임의 표준 개발 부문에 주력
참고   https://www.sae.org/

 

용어 구분   기관 및 관련 표준
용어   SAE J2735
설명   Dedicated Short Range Communications (DSRC) Message Set Dictionary
참고   https://www.sae.org/

 

용어 구분   기관 및 관련 표준
용어   SAE J2945
설명   Vehicle-to-Vehicle (V2V) 통신을 위해 OnBoard System 에 필요한 기술적 요구사항들에 대한 표준
참고   https://www.sae.org/

 


 

용어 구분   자율주행
용어   첨단 운전자 보조 시스템
영문 약어   ADAS
영문 Full name   Advanced Driver Assistance System
설명   감지센서가 위험사항을 감지하여 운전자에게 시각적, 청각적, 촉각적 요소를 통해 사고의 위험이 있음을 경고하고 이를 대처할 수 있도록 도와주는 시스템
하단, ADAS 종류
- 차량 자동 항법 장치 (In-vehicle navigation system)
- 적응형 순향 제어 장치 (ACC, Adaptive Cruise Control or Smart Cruise Control)
- 차선 유지 보조 시스템 (LDWS, Lane Departure Warning System or Lane Keeping Assist System)
- 사각지대 경고 장치 (Lane Change Assistance or Blind Spot Detection)
- 충돌 예방 시스템 (Collision Avoidance System or Precrash Safety System)
- 지능형 속도 적응 시스템 (Intelligent speed adaptation or intelligent speed advice)
- 야간 시야 시스템 (Night Vision)
- 지능형 전조등 제어 (Adaptive Front Light Control)
- 보행자 보호 시스템 (Pedestrian Protection System)
- 자동 주차 시스템 (Automatic Parking)
- 교통 표지판 인지 시스템 (Traffic Sign Recognition)
- 운전자 졸음 방지 시스템 (Driver Drowsiness Detection)
- 차량 통신 시스템 (Vehicular Communication Systems)
- 경사로 주행 제어 (Hill Descent Control)
- 전기차 주행 경고음 (Electric Vehicle Warning Sounds used in hybrids and plug-in electric vehicles)
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   잠김방지제동장치
영문 약어   ABS
영문 Full name   Anti-lock Braking Systems
설명   일반 제동장치를 단 자동차는 급제동할 경우, 바퀴의 잠김 현상 때문에 바퀴가 미끄러지는 경우가 발생한다. 또한 이러한 자동차는 차제가 옆으로 쏠리는 현상이 나타나게 된다.
반면 ABS를 장착할 시, 1초에 7·8회 바퀴를 잠갔다가 풀렀다가를 반복한다. 이를 통해 빙판길을 운전할 시 짧은 거리에서 멈출 수 있다. 또한 차체가 한쪽으로 쏠리지 않기 때문에, 급제동의 위험도 나타나지 않는다
참고   https://ko.wikipedia.org/wiki/ABS

 

용어 구분   자율주행
용어   차선 유지 보조 시스템
영문 약어   LDWS
영문 Full name   Lane Departure Warning System or Lane Keeping Assist System
설명   LDWS는 방향지시등을 켜지 않고 차선을 변경하는 경우를 감지하여, 해당 사항을 운전자에게 알려서 주고, 능동형 차량 안전 시스템을 동작시킨다.
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   차선 변경 경고
영문 약어   LCW
영문 Full name   Lane Change Warning
설명    
참고   http://savari.net/technology/applications/

 

용어 구분   자율주행
용어   충돌 예방 시스템
영문 약어   CAS or PSS
영문 Full name   Collision Avoidance System or Precrash Safety System
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   차량 자세 제어 장치
영문 약어   ESP
영문 Full name   Electronic Stability Program
설명   Bosch에서 사용하는 용어로, 자동차회사마다 이름이 다르다. Bosch가 세계 최초 개발, 적용, 상용화하였음.
달리고 있는 자동차의 속도와 회전, 미끄러짐 등을 수십분의 1초 단위로 계산하여 실제 값과 운전자가 의도한 값을 비교, 계산하여 차이가 나는 경우, 브레이크와 엔진출력 등을 운전자가 의도한 만큼 제어할 수 있도록 스스로 개입해 사고를 미연에 방지하는 기술.

기존의 수동적 안전장치인 사고가 난 이후에 운전자를 보호하는 안전벨트, 에어백 등과는 달리 능동적인 안전장치의 범주에 들어가며 사고를 미연에 예방하는 기술로, 기존의 단순 ABS(Anti-lock Brake System)와 TCS(Traction Control System) 등 모든 전자장비의 유기적인 총 집약기술이라고 볼 수 있다.
참고   https://namu.wiki/w/%EC%B0%A8%EC%B2%B4%20%EC%9E%90%EC%84%B8%20%EC%A0%9C%EC%96%B4%EC%9E%A5%EC%B9%98

 

용어 구분   자율주행
용어   전방추돌방지
영문 약어   FCW
영문 Full name   Forward Collision Warning
설명    
참고    

 

용어 구분   자율주행
용어   경사로 주행 제어
영문 약어   HDC
영문 Full name   Hill Descent Control
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   교차로 이동 지원
영문 약어   IMA
영문 Full name   Intersection Movement Assist
설명    
참고   http://savari.net/technology/applications/

 

용어 구분   자율주행
용어   교통 표지판 인지 시스템
영문 약어   TSR
영문 Full name   Traffic Sign Recognition
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   도로작업알림
영문 약어   RSA
영문 Full name   Road Safety Alert
설명    
참고    

 

용어 구분   자율주행
용어   보행자 보호 시스템
영문 약어   PPS
영문 Full name   Pedestrian Protection System
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   비상제동경고
영문 약어   EEBL
영문 Full name   Electronic Emergency Brake Light
설명    
참고    

 

용어 구분   자율주행
용어   사각지대 경고
영문 약어   BSW
영문 Full name   Blind Spot Warning
설명    
참고   http://savari.net/technology/applications/

 

용어 구분   자율주행
용어   사각지대 경고 장치
영문 약어   BSD
영문 Full name   Blind Spot Detection
설명   접근하는 자동차 그리고 사각지대에 위치한 자동차에 대한 정보를 운전자에게 제공하는 장치로 사각지대에 있는 자동차 등을 인지하지 못하고 차선을 변경하거나 근접하는 자동차로 인해 사고위험이 감지되는 경우 미연에 사고를 방지하기 위한 안전장치이다.
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   야간 시야 시스템
영문 약어    
영문 Full name   Night Vision
설명   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C
참고    

 

용어 구분   자율주행
용어   운전자 졸음 방지 시스템
영문 약어    
영문 Full name   Driver Drowsiness Detection
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   자동 주차 시스템
영문 약어    
영문 Full name   Automatic Parking
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   저속 자동 긴급 제동
영문 약어   AEB
영문 Full name   Automatic Emergency Braking System
설명   도심 저속 주행 때 장애물을 감지하면 자동으로 브레이크가 작동해 완전히 정지할 수 있도록 돕는 기능
참고    

 

용어 구분   자율주행
용어   적응형 순향 제어 장치
영문 약어   ACC
영문 Full name   Adaptive Cruise Control or Smart Cruise Control
설명   ACC는 차량 전방에 장착된 레이다를 사용하여 앞차와의 간격을 적절하게 자동 유지하는 시스템이다.
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   전기차 주행 경고음
영문 약어    
영문 Full name   Electric Vehicle Warning Sounds 
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   좌회전 지원
영문 약어   LTA
영문 Full name   Left Turn Assist
설명    
참고   http://savari.net/technology/applications/

 

용어 구분   자율주행
용어   주행 금지 경고
영문 약어   DNPW
영문 Full name   Do Not Pass Warning
설명    
참고   http://savari.net/technology/applications/

 

용어 구분   자율주행
용어   지능형 속도 적응 시스템
영문 약어   ISA
영문 Full name   Intelligent speed adaptation or intelligent speed advice
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   지능형 전조등 제어
영문 약어    
영문 Full name   Adaptive Front Light Control
설명   변화하는 도로에 대해 최적의 시야를 제공하는 지능형 전조등.
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   차량 자동 항법 장치
영문 약어   IVNS
영문 Full name   In-Vehicle Navigation System
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   차량 통신 시스템
영문 약어    
영문 Full name   Vehicular Communication Systems
설명    
참고   https://ko.wikipedia.org/wiki/%EC%B2%A8%EB%8B%A8_%EC%9A%B4%EC%A0%84%EC%9E%90_%EB%B3%B4%EC%A1%B0_%EC%8B%9C%EC%8A%A4%ED%85%9C

 

용어 구분   자율주행
용어   통제 불능 경고
영문 약어   CLW
영문 Full name   Control Loss Warning
설명    
참고    

 

용어 구분   자율주행
용어   급커브속도경보시스템
영문 약어   CSW
영문 Full name   Curve Speed Warning
설명    
참고   http://savari.net/technology/applications/

 

용어 구분   자율주행
용어    
영문 약어   WZW
영문 Full name   Work Zone Warning
설명    
참고   http://savari.net/technology/applications/

 


 

용어 구분   자율주행 장비
용어   전자 제어 유니트
영문 약어   ECU
영문 Full name   Electronic Control Unit
설명   차량의 엔진, 자동 변속기 등의 상태를 컴퓨터로 제어하는 장치로서 차량 내부의 센서들을 관리하는 역할을 수행
참고   https://committee.tta.or.kr/include/Download.jsp?filename=choan%2F%5B2014-338%5D+%C2%F7%B7%AE%B0%A3+%C5%EB%BD%C5%C8%AF%B0%E6%BF%A1%BC%AD%C0%C7+%B8%DE%BD%C3%C1%F6+%BE%CF%C8%A3%C8%AD+%B1%D4%B0%DD.docx

 

용어 구분   자율주행 장비
용어   지역 동적 지도
영문 약어   LDM
영문 Full name   Local Dynamic Map
설명   고정된 지도 정보에 차량 주위의 도로 교통 정보 및 상태 정보가 반영된 지도 데이터 베이스로서 차량으로 수신되는 메시지가 중복되었는지, 최신의 정보인지를 필터링 하는 역할을 수행
참고   https://committee.tta.or.kr/include/Download.jsp?filename=choan%2F%5B2014-338%5D+%C2%F7%B7%AE%B0%A3+%C5%EB%BD%C5%C8%AF%B0%E6%BF%A1%BC%AD%C0%C7+%B8%DE%BD%C3%C1%F6+%BE%CF%C8%A3%C8%AD+%B1%D4%B0%DD.docx

 

용어 구분   자율주행 장비
용어   차량 단말기
영문 약어   OBU
영문 Full name   On Board Unit
설명   차량에 탑재되는 차량 간 통신용 모듈
OBU는 차량 간 통신을 지원하기 위해 차량 내부에 설치되는 시스템을 의미한다. 라우팅 테이블(RT)은 이웃 차량의 위치 정보 및 타임스탬프 정보를 저장한다. 테이블 정보는 이웃 차량들로부터 수신되는 메시지로부터 구성된다. 지역적인 동적 지도(LDM)는 고정된 지도 정보에 차량 주위의 도로 교통 정보 및 상태 정보가 반영된 지도 데이터 베이스로서 차량으로 수신되는 메시지가 중복되었는지, 최신의 정보인지를 필터링 하는 역할을 수행한다. 통신 제어 유니트 (CCU)은 차량 내부 및 차량 외부의 통신을 연결하는 모듈이다. 전자 제어 유니트 (ECU)는 차량의 엔진, 자동 변속기 등의 상태를 컴퓨터로 제어하는 장치로서 차량 내부의 센서들을 관리하는 역할을 수행한다. 센서는 차량 주행에 관련된 정보를 감지하는 장치이다.
참고   https://committee.tta.or.kr/include/Download.jsp?filename=choan%2F%5B2014-338%5D+%C2%F7%B7%AE%B0%A3+%C5%EB%BD%C5%C8%AF%B0%E6%BF%A1%BC%AD%C0%C7+%B8%DE%BD%C3%C1%F6+%BE%CF%C8%A3%C8%AD+%B1%D4%B0%DD.docx

 

용어 구분   자율주행 장비
용어   통신 제어 유니트
영문 약어   CCU
영문 Full name   Communication and Control Unit
설명   차량 내부 및 차량 외부의 통신을 연결하는 모듈
참고   https://committee.tta.or.kr/include/Download.jsp?filename=choan%2F%5B2014-338%5D+%C2%F7%B7%AE%B0%A3+%C5%EB%BD%C5%C8%AF%B0%E6%BF%A1%BC%AD%C0%C7+%B8%DE%BD%C3%C1%F6+%BE%CF%C8%A3%C8%AD+%B1%D4%B0%DD.docx

 


 

용어 구분   통신 규약
용어   BSM
영문 약어   BSM
영문 Full name   Basic Safety Message
설명   SAE J2735로 정의.
주행하는 차량의 안전성을 높이기 위하여, 임의의 차량으로부터 빈번하게 브로드캐스팅되는 메시지를 의미
차량 간 통신 환경에서는 각 차량은 100msec 주기로 주변의 차량에게 BSM을 브로드캐스팅 한다. 또한 각 차량 및 RSU는 브로드캐스팅되는 BSM을 수신하여, 각 차량에서 운영되고 있는 안전 서비스에 연관되는 지를 판별하고, 필요한 내부 처리 과정을 수행하게 된다.
BSM은 Part 1 및 Part 2 라고 부르는 두 개의 섹션으로 구성된다. Part 1의 정보는 항상 전송되는 정보로서, 차량의 위치, 이동 방향, 현재 시간 및 차량의 상태 정보를 포함한다. Part 2는 부가적인 정보로서, 그 내용은 서비스의 형태에 의하여 결정된다.
참고   https://committee.tta.or.kr/include/Download.jsp?filename=choan%2F%5B2014-338%5D+%C2%F7%B7%AE%B0%A3+%C5%EB%BD%C5%C8%AF%B0%E6%BF%A1%BC%AD%C0%C7+%B8%DE%BD%C3%C1%F6+%BE%CF%C8%A3%C8%AD+%B1%D4%B0%DD.docx

 

용어 구분   통신 규약
용어   프로브 차량 데이터
영문 약어   PVD
영문 Full name   Probe Vehicle Data
설명   Unicast from a vehicle to a TMC or other infrastructure.based system
Similar to BSM, but contains additional vehicle status and traveling behavior data
Core data frames are time & location based “Snapshots”
- Snapshots contain sensor value/state at an moment in time
- A single PVD Message can contain up to 32 Snapshots
- Snapshots are generated based on
- Periodic.time/distance traveled
- "Events".when the state or status of certain Vehicle elements/systems change(on/off) (e.g. traction control system engaged) or when a pre.defined threshold is exceeded (e.g. hard braking)
- Start/Stop
- Vehicles generate and store Snapshots throughout their “trip” (ignition on .to ignition off)
- Transmitted while in communication range of a RSU
- Once the vehicle leaves communication range, and remaining messages/snapshots are deleted
참고   http://www.transportation.institute.ufl.edu/wp-content/uploads/2017/04/HNTB-SAE-Standards.pdf

 

용어 구분   통신 규약
용어   여행자 정보 매시지
영문 약어   TIM
영문 Full name   Traveler Information Message
설명    
참고    

 

용어 구분   통신 규약
용어   신호변경알림
영문 약어   SPaT
영문 Full name   Signal Phase and Timing
설명    
참고    

 


 

용어 구분   센서
용어   관성측정센서
영문 약어   IMU
영문 Full name   Inertial Measurement Unit
설명   움직이는 물체의 관성을 측정하여 전기적 신호로 출력을 내보내는 장치.
관성을 측정하여 물체가 어느 방향으로 움직이는지 알수 있음.

 

용어 구분   센서
용어   라이더
영문 약어   LIDAR
영문 Full name   LIght Detection And Ranging
설명   레이저 거리 측량기 등 빛의 파장의 특성을 이용하여 레이더로 탐지가 힘들것을 탐지함.
예: 주사식 스캐너 - 레이저 광선이 피사체에 반사된 뒤 다시 라이터 센서로 돌아오는 시간으로 거리를 계산

 

용어 구분   센서
용어   레이더
영문 약어   RADAR
영문 Full name   RAdio Detection And Ranging
설명   전자기파를 주기적으로 쏘았을 때 물체에 부딪쳐 반사되는 전자기파를 읽어와 물체와의 거리, 움직이는 방향, 높이등을 확인하는 센서

 

용어 구분   센서
용어   범지구위성항법시스템
영문 약어   GPS
영문 Full name   Global Positioning System
설명   GPS 수신기는 세 개 이상의 GPS 위성으로부터 송신된 신호를 수신하여 위성과 수신기의 위치를 결정한다. 위성에서 송신된 신호와 수신기에서 수신된 신호의 시간차를 측정하면 위성과 수신기 사이의 거리를 구할 수 있는데, 이때 송신된 신호에는 위성의 위치에 대한 정보가 들어 있다. 최소한 세 개의 위성과의 거리와 각 위성의 위치를 알게 되면 삼변측량에서와 같은 방법을 이용해 수신기의 위치를 계산할 수 있다.
참고   https://ko.wikipedia.org/wiki/GPS

 

용어 구분   센서
용어   스로틀위치센서
영문 약어   TPS
영문 Full name   Throttle Position Sensor
설명   스로틀 위치 센서는 스로틀 축과 알체로 스로틀 바디에 장착되어 있다.
스로틀은 흡입공기 통로의 중간에 위치하며, 흡입공기량의 통로로서 운전자의 악셀 페달의 어/닫힘에 의하여 엔진에 흡입되는 공기량을 조절한다. 그리고, 이 공기량의 변화에 의하여 그에 따른 분사량과 점화가 달라지게 된다. 그러므로 스로틀 위치센서는 스로틀의 열림 각도(운전자의 가/감속의 의지)를 전압값으로 읽고 ECM에 전달하는 역할을 담당하고 있다. ECM은 이 정보로서 가속 영역, 감속 영역, 연료 컷(Fuel Cut)의 판단 및 점화제어를 하고 있다.
참고   http://blog.daum.net/815carplus/57

 


 

용어 구분   자율주행 네트워크 통신
용어   RSU
영문 약어   RSU
영문 Full name   Road Side Unit
설명   노변에 설치되는 차량 간 통신을 위한 기지국
장비는 급증하는 차량 사고 및 사용자 중심의 차세대 교통 안전 서비스 제공을 목적으로 주행 중 또는 정차 중에 있는 차량 단말기(OBU, On Board Unit)와 상호 통신을 통해 보다 안정적인 서비스를 고객에게 맞춤 제공하기 위한 RF 기지국 장치
참고   http://www.highgain.co.kr/itssolution/p1.asp?stat2=155&stat3=157

 

용어 구분   자율주행 네트워크 통신
용어   V2X
영문 약어   V2X
영문 Full name   Vehicle-to-Everything
설명   운전 중 도로 인프라 및 다른 차량과 통신하면서 교통상황 등의 정보를 교환하거나 공유하는 기술
V2V, V2P, V2N, V2I, V2C 등이 존재함.

 

용어 구분   자율주행 네트워크 통신
용어   V2V
영문 약어   V2V
영문 Full name   Vehicle-to-Vehicle
설명   차량 간 통신

 

용어 구분   자율주행 네트워크 통신
용어   V2P
영문 약어   V2P
영문 Full name   Vehicle-to-Pedestrians
설명   차량과 보행자 간의 통신

 

용어 구분   자율주행 네트워크 통신
용어   V2N
영문 약어   V2N
영문 Full name   Vehicle-to-Nomadic-devices
설명   차량과 모바일 기기 간 통신

 

용어 구분   자율주행 네트워크 통신
용어   V2I
영문 약어   V2I
영문 Full name   Vehicle-to-Infrastructure
설명   차량과 인프라 간 통신

 

용어 구분   자율주행 네트워크 통신
용어   V2C
영문 약어   V2C
영문 Full name   Vehicle-to-Center
설명   차량과 관제센터 간의 통신

 

용어 구분   자율주행 네트워크 통신
용어   BBU
영문 약어   BBU
영문 Full name   Base Band Unit
설명   5G 데이터 처리 장비
참고   http://www.greened.kr/news/articleView.html?idxno=36033

 

용어 구분   자율주행 네트워크 통신
용어   cellular V2X
영문 약어    
영문 Full name   cellular V2X
설명   차량 통신 네트워크의 표준의 한 종류

 

용어 구분   자율주행 네트워크 통신
용어   LTE V2X
영문 약어   LTE V2X
영문 Full name    
설명   V2X를 위한 통신 표준 기술로, cellular V2X 방식임.

 

용어 구분   자율주행 네트워크 통신
용어   RFU
영문 약어   RFU
영문 Full name   Radio Frequency Unit
설명   5G 기지국
참고   http://www.greened.kr/news/articleView.html?idxno=36033

 

용어 구분   자율주행 네트워크 통신
용어   근거리 전용 통신
영문 약어   DSRC
영문 Full name   Dedicate Short Range Communications
설명   차량 통신 네트워크의 표준의 한 종류
차량과 노변 기지국 간 100m이내에서 1Mbps 급의 근거리 통신이 가능하여 요금징수 및 교통량 수집과 정보 제공하는 네트워킹 톤신 기술
ITS 분야에 가장 많이 적용
예: 전자요금징수, 무정차기반 자동요금지불 서비스, Hi-pass 기반 교통정보서비스, BIS(Bus Information Service)
참고   http://transpro.tistory.com/entry/DSRC%EC%99%80-WAVE

 

용어 구분   자율주행 네트워크 통신
용어   차량용 고속무선통신기술
영문 약어   WAVE
영문 Full name   Wireless Access in Vehicular Environments
설명   V2X를 위한 통신 표준 기술로, DSRC 방식임.
근거리 통신 표준에서 가장 활용도가 높은 IEEE 802.11p WiFi 기술을 자동차에 맞도록 개선하여 2012년에 완료한 표준임. (국내 표준)
고속(160km/h 이상)으로 주행하는 상황에서 차량 간 통신(V2V), 차량과 인프라 통신(V2I)을 지원하여 전방 도로 및 차량의 위험정보를 긴급 전송, 후속 추돌사고 등을 예방하는 안전서비스, 다차로 무정차톨링 서비스 등 다양한 차세대 지능형 교통시스템(ITS) 구축에 활용할 수 있는 차량 네트워킹 기술
참고   http://transpro.tistory.com/entry/DSRC%EC%99%80-WAVE

 

용어 구분   자율주행 네트워크 통신
용어   WSA
영문 약어   WSA
영문 Full name   WAVE Service Advertisement
설명    

 

용어 구분   자율주행 네트워크 통신
용어   WSM
영문 약어   WSM
영문 Full name   WAVE Short Message
설명    

 


 

용어 구분   기타
용어   버스 정보 시스템
영문 약어   BIS
영문 Full name   Bus Information Service
설명    버스의 운행과 관련된 각종 정보를 실시간 수집 가공하여 버스 이용자들에게 제공하는 첨단 교통시스템으로 첨단 통신망을 도입하여 실시간 버스 운행정보 수집, 가공을 통해 정보를 제공하는 시스템입니다.
 버스 이용자들에게는 각종 매체(정류소 안내기, 인터넷, 휴대폰 등)를 이용하여 버스도착예정시간, 버스위치정보 등을 제공하는 신개념 대중교통 시스템입니다.
 버스운전자를 위한 노선정보, 운행 정보 등의 제공으로 차량운행 관리 서비스를 제공합니다.
참고   https://bus.jeju.go.kr/introduction/bisInfo

 

용어 구분   기타
용어   지능형 교통 시스템
영문 약어   ITS
영문 Full name   Intelligent transportation system
설명   도로·차량·화물 등 교통의 구성요소에 통신기술을 적용하여 교통정보를 수집·관리·제공함으로써, 교통시설의 이용효율을 극대화하고, 통행자에게 유용한 정보를 제공하여 교통 이용 편의와 교통안전을 제고하고, 에너지절감 등 환경친화적 교통체계를 구현하는 지능형교통체계입니다.
참고   http://www.c-its.kr/introduction/introduction.do

 

용어 구분   기타
용어   지능형 교통 시스템차세대ITS
영문 약어   C-ITS
영문 Full name   Cooperative-Intelligent Transportation System
설명   차량이 주행 중 운전자에게 주변 교통상황과 급정거, 낙하물 등의 사고 위험 정보를 실시간으로 제공하는 시스템.
현(現) ITS는 교통수단과 시설이 분리된 상태에서 교통관리 또는 교통소통 중심의 정보수집 및 제공시스템인 반면에 차세대ITS(C-ITS)는 개별차량에 대하여 실시간 정보를 제공하여 돌발상황에 사전대응 및 예방이 가능합니다.
참고   http://www.c-its.kr/introduction/introduction.do

 

 

 

 

'New Tech. > Autonomous Driving' 카테고리의 다른 글

V2X (Vehicle-to-Everything)  (0) 2020.04.16
ECU / CAN / LIN / OBD  (0) 2020.04.16
자율주행차 정의 및 관련 센서  (0) 2020.04.16

* 성능 개선율 : (튜닝 전 - 튜닝 후) / 튜닝 후

 

 

[ 튜닝 전 ]

 

  아래 쿼리를 살펴보도록 하겠습니다.

SELECT CNT1, CNT2, CNT3, CNT4, CNT5, CNT6, CNT7, CNT8 
 FROM (
       SELECT (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='0' AND LOG_LVL='1') CNT1
            , (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='1' AND LOG_LVL='1') CNT2
            , (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='2' AND LOG_LVL='1') CNT3
            , (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='3' AND LOG_LVL='1') CNT4
            , (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='4' AND LOG_LVL='1') CNT5
            , (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='5' AND LOG_LVL='1') CNT6
            , (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='6' AND LOG_LVL='1') CNT7
            , (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='7' AND LOG_LVL='1') CNT8
         FROM DUAL
    ) A;

  CHG_LOGS 테이블의 조건별 건수를 출력하는 쿼리입니다.
  ST_CD 값 별 데이터 건수를 계산하기 위해 스칼라 서브 쿼리 안에서 CHG_LOGS 테이블을 액세스하고 있습니다. 문제는 유사한 스칼라 서브 쿼리가 총 8개가 존재한다는 점입니다. 다시 말해서, CHG_LOGS 테이블을 8번 중복해서 액세스 한다는 뜻입니다.

 


  위 쿼리의 AUTOTRACE 결과를 확인해보겠습니다.

  위 쿼리의 실행계획을 살펴보면 아래와 같은 패턴(인덱스 스캔 및 테이블 랜덤 액세스)을 8번 반복해서 수행한 것을 확인할 수 있습니다.

  위와 같은 반복적인 액세스 작업 때문에 과도한 블럭 읽기(109,718블럭)가 발생하고 이로 인하여 쿼리 수행 시간도 길어지게 되었습니다.

  그럼, 어떤 방식으로 중복 액세스를 제거하여 쿼리 성능을 높일 수 있는지 확인해보도록 하겠습니다.

 

 

[ 튜닝 후 ]

 

  아래는 튜닝 후 쿼리입니다.

 

SELECT NVL( SUM( CASE WHEN ST_CD='0' THEN 1 ELSE 0 END), 0) AS CNT1
     , NVL( SUM( CASE WHEN ST_CD='1' THEN 1 ELSE 0 END), 0) AS CNT2
     , NVL( SUM( CASE WHEN ST_CD='2' THEN 1 ELSE 0 END), 0) AS CNT3
     , NVL( SUM( CASE WHEN ST_CD='3' THEN 1 ELSE 0 END), 0) AS CNT4
     , NVL( SUM( CASE WHEN ST_CD='4' THEN 1 ELSE 0 END), 0) AS CNT5
     , NVL( SUM( CASE WHEN ST_CD='5' THEN 1 ELSE 0 END), 0) AS CNT6
     , NVL( SUM( CASE WHEN ST_CD='6' THEN 1 ELSE 0 END), 0) AS CNT7
     , NVL( SUM( CASE WHEN ST_CD='7' THEN 1 ELSE 0 END), 0) AS CNT8
  FROM CHG_LOGS A
 WHERE REG_DT=:B1
   AND LOG_LVL='1';

  중복 액세스를 피하기 위해 스칼라 서브 쿼리를 제거하였습니다. CHG_LOGS 테이블은 한 번만 액세스 하도록 변경하였으며, WHERE 절에는 각 스칼라 서브 쿼리에서 동일하게 적용되었던 조건(REG_DT=:B1 AND LOG_LVL='1')을 입력하였습니다.
  그리고 CASE문을 이용하여 ST_CD 별 데이터 건수를 계산하였습니다.

 

  위와 같이 변경된 쿼리의 AUTOTRACE 결과는 아래와 같습니다.

 

  실행계획을 살펴보면 IX_CHG_LOG 인덱스와 CHG_LOGS 테이블을 한번씩 액세스하고 있는 것을 확인하실 수 있습니다. 액세스 중복이 제거되어 실행시간(0.02초)과 블럭 읽기(13,714블럭)가 감소된 것을 확인하실 수 있을 것입니다. 물론, 중복 제거의 방법으로 함수를 사용하여 CPU의 사용량이 증가하게 됩니다. 하지만, 쿼리에서 가장 큰 부하는 블럭 읽기이기 때문에 부하 측면에서 CPU 사용량은 상대적으로 낮은 비용이라고 판단할 수 있습니다.

 

  지금까지 살펴봤던 SQL 튜닝 방법이 집합적 사고의 한 예라고 볼 수 있습니다. 데이터 블럭 하나하나가 퍼즐 조각이며, 각 퍼즐 조각을 최대한 적게 활용하여 멋진 작품인 결과물을 만들어내는 게 집합적 사고에 의한 쿼리문 작성인 거죠. 많은 분들이 시간적 여유를 갖고 적은 퍼즐 조각으로 멋진 작품을 탄생시키는 기쁨을 느껴보셨으면 좋겠습니다.

  

 

  데이터의 가치가 높아지고 데이터 저장/관리 기술이 발전하면서 다양한 데이터베이스 소프트웨어가 출시되고 있습니다.

  Hadoop 클러스터링 환경에 기반한 Hive, HBase, Spark SQL는 빅데이터 수집/분석에 대한 요구사항의 증대와 같이 사용량도 늘어가고 있습니다.
  인프라 운영에 대한 리스크를 줄여주고 빠른 서비스 구축이 가능하다는 장점을 내세워 급속도로 성장을하고 있는 클라우드 서비스 플랫폼이 증가하면서 클라우드 환경의 데이터베이스도 사용이 증가하고 있습니다. 기존의 데이터베이스가 클라우드 환경에서도 서비스를 시작하는 경우도 있지만, Amazon DynamoDB, Google BigQuery, Microsoft Azure SQL Database 처럼 클라우드 플랫폼 전용 데이터베이스 서비스도 생겨나고 있습니다.
  그 외에도 다양한 형태의 데이터를 관리하기 위해 NoSQL, Graph DB, Time Series DB 등의 데이터베이스도 사용량이 증가하고 있습니다.

  하지만, 아직도 DBMS 시장에서 우위를 차지하고 있는 것은 역시 RDBMS입니다.

[출처] https://db-engines.com/en/ranking

  제가 예상하건데 표 형태로 데이터를 보고 싶어하는 사용자의 욕망이 바닥으로 추락하지 않는 한 RDBMS는 끝까지 건재할 것입니다.

 

  아무튼, 이번 포스팅에서는 이 RDBMS의 성능 최적화 전략에 대해서 정리해보고자 합니다. 

  우선, 'RDBMS'의 성능이 좋다는 기준은 무엇일까요?
  RDBMS의 목적이 동시성 제어로 다수의 사용자가 빠르게 원하는 데이터를 저장하고 추출하는 것이니, 얼마나 많은 사용자가 얼마나 빨리 데이터를 처리할 수 있느냐가 성능의 기준이 되겠습니다.
  실제로 SI 프로젝트에서도 위와 같은 기준으로 성능 부하 테스트를 진행하고 있습니다.

  그럼 쿼리 실행 속도가 매우 빠르면 성능상으로 문제가 없는 걸까요?
  실행 속도가 빠르다는 건 표면상의 성능 기준이라고 할 수 있습니다. 정확하게 얘기하면  쿼리 실행 시 내부적으로 얼마나 많은 블럭을 I/O했는지가 성능을 판가름하는 중요한 지표가 됩니다. 모든 시스템에서 디스크 I/O는 상대적으로 느린 속도로 인하여 많은 비용을 유발하는 원인으로 인식하고 있습니다. 그래서 디스크 I/O를 줄이기 위해 버퍼에 데이터를 로딩하여 사용합니다. 하지만 버퍼는 크기의 한계가 있기 때문에 디스크 I/O를 완전히 제거할 수는 없습니다.
  최소한의 블럭 I/O로 버퍼의 활용도를 높이고 디스크 I/O를 줄이는 것이 실행 속도를 빠르게 하고 성능을 높일 수 있는 궁극적인 방법이 되겠습니다.

  이 포스팅에서 언급하는 내용들은 거의 다 블럭 I/O를 줄이기 위한 방법들이라고 이해하시면 됩니다.
  그럼 본격적으로 RDBMS의 성능에 대해 얘기해보겠습니다. 

  필자가 생각하는 RDBMS에서의 성능 최적화 전략은 다음과 같습니다.

- RDBMS 성능 최적화 전략 -

1. 파라미터 튜닝 (Parameter tuning)
2. 조인 전략 (Join strategy)
3. 인덱스 전략 (Index strategy)
4. 데이터 아키텍처 전략 (Data architecture strategy)
5. SQL 튜닝 (SQL tuning)

 

RDBMS 성능 최적화 전략

 

 

 

1. 파라미터 튜닝 (Parameter tuning)

  파라미터(또는 Config, 환경설정) 튜닝을 제일 먼저 언급하는 이유는 시스템 구축 초기에 완료해야 할 작업이기 때문입니다.

  모든 솔루션은 설정 파일을 이용해 각 사이트 환경에 적합한 파라미터 값을 설정할 수 있는 기능을 제공합니다. (예를 들어 오라클은 init.ora, MySQL는 my.cnf 파일이 이에 해당됩니다.) 일반적인 파라미터 항목은 버퍼/캐쉬 크기, 로그 기록 위치, 블럭(페이지) 크기, 부가 기능 사용여부 또는 설정 값 등이 있을 수 있습니다.

  여러 파라미터 중에서 초기 데이터베이스 생성 시에만 설정이 가능한 항목들이 있고, 데이터베이스 생성 후에도 변경이 가능한 항목들도 존재합니다. 그렇다고 추후에 변경 가능한 항목들을 마음껏 변경할 수 있다는 뜻은 아닙니다. 특히, 운영 중인 시스템의 설정 값은 더욱 더 심사숙고 해야 합니다.
  검증되지 않은 설정 값 변경으로 기존에 잘 수행되던 쿼리의 실행계획이 변경되어 악성 쿼리가 난무하는 시스템을 만나게 될 수 도 있기 때문입니다.

  그러면 최적화를 위해 파라미터를 어떻게 변경해야 할까요?

  최선의 방법은 reference를 참조를 해서 연구하고 테스트 후 적용하는겁니다. 각 DBMS 솔루션은 사용자들을 위한 커뮤니티나 서포트 페이지를 통해서 고객 문의를 지원해주고 있습니다. 그곳에서 빈번하게 수정해야 된다고 언급되는 파라미터가 있다면 테스트 후 적용해 볼 가치가 높은 편이라고 볼 수 있습니다.

  물론 설정 값을 변경하는 것은 그저 타이핑을 하면 되는 쉬운 것이지만, 그 값을 어떤 항목으로 채워야 하는지 알아내는 것은 쉬운 일이 아닙니다. 이럴 때는 솔루션 고객센터나 데이터베이스 컨설팅 업체의 도움을 받아야 할 것입니다. 이것도 비용상의 문제로 어렵다면 DBMS 선택 시 안정화된 버전을 설치하는 것이 쉬운 방법이 될 것입니다.
  파라미터를 변경하는 주된 이유는 아직 안정화가 안된 버전에서 신규 기능에 의해 잘 알려지지 않은 버그를 해결하기 위한 경우가 많기 때문입니다.

 

2. 조인 전략 (Join strategy)

  일반적으로 우리가 알고 있는 조인 종류(Type)는 다음과 같습니다.

조인 종류


  위 조인 종류는 두 테이블을 조인 시 한 쪽에만 존재하는 데이터를 결과 데이터 셋에 포함시킬지 여부에 따라 조인을 구분한다고 생각하시면 됩니다. 자세한 내용은 아래 포스팅을 참고 바랍니다.

 

테이블 조인 종류(Table Join Type)

데이터베이스에서 데이터는 다수의 테이블에 나뉘어 저장되어 있습니다. 데이터의 중복을 제거하고 무결성을 보장하기 위해서 데이터 성격에 따라 분류하여 테이블에 저장을 하는 겁니다. 이렇게 테이블별로 분리..

sparkdia.tistory.com



  그리고 조인 방식(Method)에 의해서도 조인을 구분할 수 있습니다.


  데이터베이스 내부에서 각각의 Row를 매핑 시 사용되는 방식에 의해 조인을 구분할 수 있는겁니다.
  쿼리 실행 시 옵티마이저가 다양한 조인 방식 중에서 어떤 방식을 채택하느냐에 따라 쿼리 성능이 크게 달라질 수 있게 됩니다. 일반적으로 데이터 건수가 적은 경우에는 Nested loops join을 사용하고, 데이터 건수가 많은 경우에는 Hash join을 사용합니다. 그리고 조인 대상 테이블 중에 데이터 건수가 적은 테이블부터 액세스를 해야 더 좋은 성능을 보장할 수 있습니다.

  자세한 조인 방식에 대한 설명은 아래 포스팅을 참고 바랍니다.

 

테이블 조인 방식(Table join method)

테이블 조인 방식은 테이블의 각 로우를 매핑 시 어떤 메커니즘을 사용하느냐에 따라 조인을 구분하는 겁니다. 데이터 셋의 건수 등을 기반으로 옵티마이져가 적합한 조인 메커니즘을 선택하여 실행 계획을 생성하..

sparkdia.tistory.com

 

 

3. 인덱스 전략 (Index strategy)

  인덱스는 테이블의 데이터를 빠르게 액세스하기 위한 목적으로 만들어진 객체입니다.
  흔히 비유하기를 책 분류기호를 이용해 서가에 순서대로 정리되어 있는 책을 찾는 방법과 비슷하다고 설명합니다.

  인덱스에서는 책의 분류기호 대신에 테이블의 컬럼 값을 사용해 데이터 위치를 검색합니다. 컬럼의 값을 B-Tree 구조체에 입력하고, 루트노드부터 리프노드까지 짧은 액세스 단계를 거쳐 검색 대상 컬럼의 값이 위치한 로우의 위치(Rowid)를 빠르게 찾을 수 있게 됩니다. ( 이 포스팅의 주 목적이 B-Tree가 아닌 관계로 상세한 입력/검색 절차는 생략하겠습니다. )

B-Tree 구조


  데이터를 빠르게 검색할 수 있는 인덱스, 그렇다고 테이블 하나에 다수의 인덱스를 생성하게 되면 테이블에 데이터 입력/변경/삭제 시 인덱스의 변경 작업량이 증가하여 성능 부하의 원인이 될 수 있습니다.

  인덱스를 무조건 많이 생성하는 것보다, 인덱스의 활용도가 높아지도록 조인이나 필터링 조건으로 많이 사용되는 컬럼(흔히 액세스 패턴을 확인한다고 합니다.) 중심으로 인덱스를 생성하는 것이 중요합니다.
  즉, 자주 사용되는 쿼리문을 분석한 액세스 패턴 결과를 토대로 인덱스 컬럼을 선정해야 합니다.

  인덱스 컬럼을 선정할 때도 단일 컬럼을 선정하는 것보다는 복합 컬럼을 선정하는 것이 성능상 유리합니다. 일반적인 조회 쿼리를 보면 조인이나 필터링 조건에 하나의 컬럼만 사용되는 경우는 극히 드물기 때문입니다. 최대한 인덱스에서 조건에 맞지 않는 로우를 필터링해야만 인덱스에서 rowid를 이용해 테이블에 액세스(Random access)하는 횟수를 줄일 수 있기 때문입니다. 인덱스를 거쳐 테이블의 블럭을 읽은 횟수가 전체 테이블의 블럭 숫자보다 많다면 Full table scan이 더 유리할 것입니다.

  그리고 인덱스 컬럼의 순서도 중요합니다. 선행 컬럼의 분포도가 좋다면 인덱스 블록 액세스를 최소화 할 수 있기 때문입니다. 선행 컬럼의 분포도가 좋지 않아서 검색 조건의 값이 여러 리프 노드 블럭에 존재하는 것보다는, 좋은 분포도로 인해 적은 리프 노드 블록에 존재하는 것이 인덱스의 블럭 액세스를 줄이는 방법입니다.

  이 외에도 인덱스 스캔 방법 선택도 성능을 위해 고려해야할 사항입니다.
  오라클에서 제공하는 인덱스 스캔 방법은 아래와 같습니다.

   위 인덱스 스캔 방법에 대해서는 추후에 별도로 포스팅하도록 하겠습니다.

 

 

4. 데이터 아키텍처 전략 (Data architecture strategy)

  우선 데이터 아키텍처의 정의부터 살펴보겠습니다.

[ dbguide.net ]
데이터아키텍처란 기업의 모든 업무를 데이터 측면에서 처음부터 끝까지 체계화하는 것이다.
데이터아키텍처 전문가란 효과적인 데이터아키텍처 구축을 위해 전사아키텍처와 데이터품질관리에 대한 지식을 바탕으로 데이터 요건분석, 데이터 표준화, 데이터 모델링, 데이터베이스 설계와 이용 등의 직무를 수행하는 실무자를 말한다.

 

[ wikipedia.org ]
Data architecture is composed of models, policies, rules or standards that govern which data is collected, and how it is stored, arranged, integrated, and put to use in data systems and in organizations.

  지극히 학문적인 정의라서 쉽게 가슴에 와닿지는 않을 수도 있습니다.
  그럼 위 정의를 기반으로 데이터 아키텍처에서 고려해야 할 항목들을 정리해 보도록 하겠습니다. 제가 지금 생각나는 대로 기술하는 것이기 때문에 아래 항목들이 100% 정답이라고 단정 지을 수는 없습니다.


데이터 요구분석
데이터베이스 선택 (ex : RDBMS, NoSQL, 그래프 DB, 임베디드DB, etc.)
서버/클러스터 구성 (ex: 단일 서버, HA구성, 클러스터 구성, RAC, Max scale, etc.)
파일 시스템 선택 (Oracle : OS Filesystem vs ASM vs Raw device)
데이터베이스 저장 엔진 선택 (MariaDB : Innodb, Aria, XtraDB, etc.)
데이터 표준화 (단어/용어/도메인)
데이터 모델링 (개념/논리/물리, 주제영역)
데이터 간 관계 정의
데이터 인터페이스 정의
데이터 수집 방법 및 범위 (ex : App. 생성 데이터, 외부 연계, 통계 데이터, 시스템 운영 데이터, etc.)
오브젝트 사용 정책 (ex: 트리거 사용 여부, PL/SQL 사용 여부, FK 설정 여부, 최대 인덱스 생성 허용 갯수, etc.)
명명 규칙 (ex: 테이블명, 테이블스페이스명, 인덱스명, 사용자계정명, etc.)
데이터베이스 사용자 계정/권한 정책
데이터베이스 접근 제어 정책
데이터 보관 주기
데이터 로그 관리
데이터 백업 전략
...


  위 항목들 외에도 제가 지금 생각하지 못한 데이터 아키텍처 항목들이 더 많을 수도 있습니다.

  그리고 위 항목들은 하나의 데이터베이스를 사용한다는 전제하에 List-up을 한 것입니다. 요즘에는 시스템 규모가 커지고 있기 때문에 한 시스템에서도 다양한 데이터베이스를 사용하도록 설계하는 곳도 많습니다.

  예를 들어, MariaDB/MySQL의 replication기능으로 데이터를 여러 서버에 복제 해두고 특정 사용자는 특정 서버의 데이터베이스를 액세스 하도록 구성하여 부하가 분산되게 구성할 수 있습니다. 이 때, 사용자가 어떤 서버의 데이터베이스를 사용해야 하는지 알려주는 역할은 동시 접근성이 좋은 오라클이 할 수 있는것입니다.

  사용자가 처음 시스템에 접속하면 오라클한테 '어느 서버를 이용하면 되나요?'라고 문의하고, 오라클이 'N번 서버의 데이터베이스를 이용하세요.'라고 응답하면, 그 후로 사용자는 계속 N번 서버의 데이터베이스와 통신을 하게 되는 겁니다.

  위의 데이터베이스 구성 방법은 단순한 예시일 뿐입니다. 요즘 MariaDB에서도 MaxScale으로 부하 분산 기능이 강화되었으니 MariaDB만으로도 안정적으로 운영이 가능 할 것입니다.

  아무튼, 데이터 아키텍처 설계라는게 단순히 데이터 모델만 그려내는 작업만이 아니라 더 포괄적으로 정책이나 성능 향상을 위한 방법까지도 정의해야 합니다.

  본론으로 들어가서, 데이터 아키텍처의 성능 향상 방법, 구체적으로 물리 데이터 모델의 성능 향상 방법에 대해 논의하고자 합니다.

  필자가 생각하는 물리 데이터 모델의 성능 향상 방법(의 일부)은 아래와 같습니다.

 

4-1) Partitioning

  데이터베이스에서 파티션은 크기가 큰 테이블이나 인덱스를 관리하기 용이하도록 작은 단위로 쪼개서 저장하는 단위입니다.

  한 회사에서 10년간의 거래 내역을 엑셀로 관리하고 있는데, 주로 거래 내역을 입력하고 확인하는건 최근 한달간의 데이터라고 가정해보겠습니다.
  만약, 전체 거래 내역이 하나의 엑셀 파일에 저장되어 있다면 어떻게 될까요? 엑셀 파일이 너무 커서 원하는 데이터를 찾는 것도 어려울 것이고, 컴퓨터의 자원을 많이 소비하여 처리 속도도 느려질 것입니다.
  이 때, 엑셀 파일을 월 단위로 나눠서 저장하게 되면 어떻게 될까요? 전체 테이터를 저장한 파일에 비해 경량의 엑셀 파일이 될 것입니다. 물론 데이터를 찾고 입력하는 속도도 빨라질 것이고요.

  위와 같이 데이터베이스에서 기준에 의해 데이터를 분리하여 저장/관리하는 것이 파티션의 역할입니다.
  기준에 의해 데이터가 분리되어 있기 때문에 검색 조건에 기준 컬럼 조건이 포함되어 있다면 전체 테이블 데이터가 아니라 조건에 맞는 파티션 데이터만 액세스(Partition pruning이라고 합니다.)하게 되므로 블록 액세스가 감소됩니다.

  아래 예제를 살펴보겠습니다.


  테이블에서 YYYYMM 컬럼 값이 '201903'인 데이터를 조회하는 쿼리를 실행했습니다. 일반 테이블에서 YYYYMM='201903'인 값을 찾기 위해서는 전체 테이블을 탐색해야 합니다. 
  만약, YYYYMM 컬럼 값을 기준으로 파티션이 된 테이블에서 YYYYMM='201903'인 값을 찾는다면 YYYYMM='201903'에 해당하는 파티션만 탐색하게되므로 블록 액세스가 감소됩니다.

  데이터베이스에서 성능 향상을 위한 기본이 블록 액세스를 줄이는 것이니, 파티션을 사용하면 데이터베이스의 성능이 향상 될 수 있게됩니다.

  그리고 오라클에서 테이블이나 인덱스를 파티셔닝하게되면 파티션 별로 세그먼트라는 논리적 저장 구조가 분리되어 관리되고, 데이터 파일도 분리(파티션 별 테이블스페이스 설정 작업이 별도로 필요합니다.)되게 됩니다. 물리적으로도 데이터 I/O에 대한 부하가 감소되는 겁니다.

  그러나 파티셔닝으로 인해 성능 향상이 기대 된다고 모든 테이블을 파티션 테이블로 생성해야 하는 것은 아닙니다.
  크기가 작은 테이블을 파티셔닝하게 되면 관리 포인트가 증가하게 되고, 여러 세그먼트에 분산되어 저장되기 때문에 테이블의 전체 블럭 갯수가 증가할 수 있게 됩니다. 데이터가 대용량이고 기준 조건(파티션 키 컬럼)으로 조회가 빈번한 테이블만 파티션 대상이 됩니다.

  만약 파티션 대상 테이블을 선정했다면 테이블 별 파티션 전략도 수립해야 합니다.
  아래 목록은 오라클에서 지원하는 파티션의 종류입니다. 데이터 요건과 테이블 액세스 패턴을 고려하여 각 테이블에 적합한 파티션 전략을 선택하면 됩니다.

파티션 종류 설명
Range Partitioning 파티션 키 컬럼 값의 범위를 기준으로 파티셔닝을 합니다.
예를들어, DT 컬럼(YYYYMMDD)이 파티션 키 컬럼일 때
  'PART_1999' 파티션에는 DT 컬럼 값이 '20000101' 미만인 데이터,
  'PART_2000' 파티션에는 DT 컬럼 값이 '20000101' 이상 '20010101' 미만인 데이터,
  'PART_2001' 파티션에는 DT 컬럼 값이 '20010101' 이상 '20020101' 미만인 데이터를 저장하게 됩니다.
Interval Partitioning Range 파티셔닝은 파티션을 운영자가 직접 범위를 명시하고 생성해줘야 합니다.
이런 단점을 극복한 것이 Interval 파티셔닝입니다. Range 파티션에서 기존에 생성된 파티션 조건에 맞지 않는 데이터가 입력되면 데이터베이스가 Interval을 기준으로 신규 파티션을 자동으로 만들어주게 됩니다.
List Partitioning 파티션 키 컬럼 값을 기준으로 파티셔닝 합니다.
예를 들어, CODE 컬럼이 파티션 키 컬럼일 때
 'PART_A_B' 파티션에는 CODE 컬럼 값이 'A'나 'B'인 데이터,
 'PART_C_D' 파티션에는 CODE 컬럼 값이 'C'나 'D'인 데이터를 저장하게 됩니다.
Hash Partitioning 파티션 키 컬럼 값의 해쉬 함수 연산 결과 값을 기준으로 파티셔닝 합니다.
Reference Partitioning 부모 테이블의 파티션 전략을 그대로 상속받게 됩니다. Reference 파티션 테이블에는 부모 테이블에 대한 Foreign Key가 설정되어 있어야 합니다.
Composite Partitioning 파티션 아래에 서브 파티션을 생성하게 됩니다.
서브 파티션은 Range, List, Hash 파티션만 가능합니다.



  인덱스도 파티셔닝에 따라 아래와 같이 구분되어 질 수 있습니다.

[출처] https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/partitions-views-and-other-schema-objects.html

 

구분 설명
Global Partitioned Index 테이블의 파티션 전략과는 독립적으로 인덱스만의 파티션 전략으로 파티셔닝된 인덱스
Local Partitioned Index 테이블의 파티션 전략과 동일하게 파티셔닝된 인덱스
Local Prefixed Index 테이블 파티션 키 컬럼과 인덱스의 첫 번째 컬럼이 동일한 인덱스
Local Nonprefixed Index 테이블 파티션 키 컬럼과 인덱스의 첫 번째 컬럼이 상이한 인덱스

  인덱스 파티션도 테이블 파티션과 마찬가지로 데이터 요건과 테이블 액세스 패턴을 고려하여 각 테이블에 적합한 파티션 전략을 선택해야 합니다. 
  일반적으로 Local Partitioned Index나 Nonpartitioned Index의 생성 비율이 높은 편이며, Local Nonprefixed Index는 실무에서는 거의 볼 수 없는 구조입니다.

 

4-2) View와 UDF 사용 최소화 (At least view and UDF)

  View는 테이블과는 다르게 별도의 저장 공간이 존재하지 않는 객체입니다. 단지 View 생성 시 정의한 SQL문이 데이터베이스에 저장되어 있으며, 사용자가 뷰를 조회 할 때 마다 저장된 SQL문을 실행하여 결과를 보여주게 됩니다.

  View를 사용하게 되면 아래와 같은 장점이 있습니다.
  첫 번째, 정보 보안성을 강화할 수 있습니다. 예를 들어, 고객 테이블에서 주민등록번호 등과 같은 개인 정보는 일반 데이터베이스 사용자에게 공개할 수 없다는 보안 정책이 존재할 수 있습니다. 이런 경우 고객 테이블에서 주민등록번호 컬럼을 제외한 나머지 컬럼만 조회하는 View를 생성하고 일반 사용자는 View를 통해 주민등록번호가 제외된 고객 정보를 조회할 수 있도록 처리할 수 있습니다.
  두 번째, 쿼리 작성의 복잡도를 줄여줍니다. 아주 복잡한 수식이 사용된 쿼리문이나 길이가 긴 쿼리문을 View로 생성할 수 있습니다. 복잡한 쿼리문 대신에 View를 사용하게 되면 쿼리문이 간결해져서 가독성이 좋아집니다.

  물론, View의 단점도 존재합니다.
  첫 번째, 관리 포인트가 많아집니다. 너무 많은 View 생성을 남발하게되면 당연히 관리해야할 객체가 증가하게 되어 이 또한 관리 포인트가 됩니다. 더 큰 문제는 View에서 액세스하고 있는 테이블이 변경되면 View에도 영향이 있을 수 있다는 겁니다. View 쿼리문에 직접 명시된 컬럼이 변경 대상이 아니라면 큰 이슈는 없을 것입니다. 하지만, 'SELECT * FROM 테이블명'과 같이 전체 컬럼 조회를 뜻하는 *(Asterisk)를 사용한 경우에는 관련 쿼리문을 수정해야 하는 사태가 발생할수도 있습니다.
  두 번째, 성능 부하의 원인이 될 수 있습니다. View 조회 시 데이터 필터링을 위해 WHERE 조건을 사용 할 수 있습니다. 정상적인 경우라면 Optimizer가 View의 Where 조건절도 테이블의 필터링 조건으로 인식하여 인덱스 사용 등의 최적화된 실행 계획을 생성하게 될 것입니다. 하지만 View안의 쿼리가 복잡한 경우 Optimizer는 우선 View를 실행 한 후 마지막에 Where 조건을 필터링하여 결과를 출력할 수도 있습니다. 출력 결과는 1~2건인데 내부적으로는 Full table scan이 발생할 수도 있다는 겁니다.

  위와 같은 이유로 필자는 보안을 위한 View외의 무분별한 View 생성은 최소화해야 된다는 원칙을 가지고 있습니다.

  UDF(User Defined Function, PL/SQL)도 마찬가지입니다.
  복잡한 계산 수식을 절차적으로 해결하기 위해 PL/SQL을 사용하여 UDF을 생성하는 경우가 있습니다. 물론, UDF를 사용하면 쿼리문이 간결해지는 장점이 있습니다.

  하지만, UDF는 View처럼 성능 부하를 유발하는 폭탄이 될 수도 있습니다.
  SELECT절에 사용된 UDF의 호출 횟수는 데이터 결과 셋의 건수와 동일합니다. 데이터 결과 셋의 건수가 10만건이라면 UDF는 10만번 수행이 되게 됩니다. 수행 횟수가 증가하니 UDF내 쿼리의 실행 횟수도 증가하여 결국 과도한 블럭 액세스를 유발하게 됩니다.

  UDF처럼 SELECT절에서 사용되는 서브 쿼리(스칼라 서브 쿼리)의 사용 여부에 따른 블럭 읽기 횟수를 비교해보도록 하겠습니다.

튜닝 전 (스칼라 함수 사용) 튜닝 후 (스칼라 함수 제거)
SQL > SELECT S.SALE_DT
                     , S.PROD_NO
                     , (SELECT PROD_NM 
                          FROM PROD P 
                        WHERE P.PROD_NO = S.PROD_NO)
                     AS PROD_NM

              FROM PROD_SALE S
            WHERE S.SALE_DT = '20200301';
SQL > SELECT S.SALE_DT
                     , S.PROD_NO
                     , P.PROD_NM
              FROM PROD_SALE S
                      , PROD P
            WHERE P.PROD_NO = S.PROD_NO 
                AND S.SALE_DT = '20200301';

  위의 두 쿼리는 PROD_SALE 테이블에서 SALE_DT 값이 '20200301'인 데이터를 추출하는 쿼리입니다. PROD_SALE 데이터 중 PROD_NO에 매핑되는 PROD_NM 값을 추출하기 위해 PROD 테이블을 액세스 합니다.
  왼쪽 튜닝 전의 쿼리에서는 스칼라 서브 쿼리를 이용해 PROD 테이블의 PROD_NM 컬럼 값을 추출합니다.
  오른쪽 튜닝 후의 쿼리에서는 PROD 테이블을 조인하여 PROD_NM 컬럼 값을 추출합니다.

  위 쿼리의 AUTOTRACE 실행 결과는 아래와 같습니다.

스칼라 함수 사용/제거 시 AUTOTRACE 결과 비교

  왼쪽 스칼라 서브 쿼리를 사용한 쿼리의 consistent gets 값은 '169,858'입니다.
  오른쪽 조인을 사용한 쿼리의 consistent gets 값은 '44,835'입니다.
  스칼라 서브 쿼리 사용 시 블럭을 읽은 횟수가 약 4배정도 많은 것을 확인 할 수 있습니다.

  위 스칼라 서브 쿼리처럼 SELECT 절에 사용되는 FUNCTION과 PROCEDURE도 마찬가지입니다. 데이터의 출력 결과 건수만큼 실행되게 되어 블럭 읽기가 증가하게 됩니다. 만약, FUNCTION이나 PROCEDURE 내 쿼리에서 Full table scan이 발생한다면 데이터 건수만큼 Full table scan이 발생하게 됩니다. 심각한 성능 저하의 원인이 되는거죠.

   이 문제를 해결하는 방법은 위 스칼라 서브쿼리처럼 FUNCTION과 PROCEDURE을 제거입니다.
  구체적인 예제는 아래 포스트를 참고하시면 됩니다.

 

 

Oracle SQL 튜닝 예제 #2 - PL/SQL 제거

비효율적인 PL/SQL(Function)을 제거하여 성능을 높인 쿼리 예제를 살펴보도록 하겠습니다. 이 포스트에 사용된 예제는 부하를 유발하는 PL/SQL를 보여주기 위해 임의로 작성된 쿼리입니다. 최대한 가독성을 높이..

sparkdia.tistory.com

 

4-3) 데이터 모델 변경(Change data model)

  데이터 모델 설계가 중요한 이유 중의 하나는 설계가 완료된 이후에는 변경이 어렵다는 점입니다.

  건축 설계를 예를 들어보겠습니다. 높은 빌딩이 완공되어 완공식을 하는데, 건물주가 1층 로비의 천장이 너무 낮다는 의견을 내놓았습니다. 완공된 건물의 1층 로비 천장을 높이기 위해 2층 바닥을 뚫기라도 해야 한다는 건가요? 절대 불가능한 일인 것입니다.

  데이터 모델도 마찬가지입니다. 오픈된 시스템의 설계 오류를 발견하더라도 큰 구조의 변경은 쉽지 않은게 현실입니다. 더군다나 24시간 365일  서비스를 하는 시스템이라면 더더욱 힘든 일이죠.

  그래도 성능 이슈를 해결하기 위해 어쩔수 없이 데이터 모델을 변경을 선택해야 하는 경우도 발생합니다.

  집계성 테이블의 경우는 데이터 모델 관점에서는 데이터 중복에 해당되므로 설계 시 최대한 생성을 배제해야 할 대상입니다. 하지만, OLTP시스템에서도 월 판매 현황 같은 집계성 데이터를 자주 조회하는 경우도 존재합니다. 이런 요건이 있다면 데이터가 중복이더라도 데이터베이스 성능을 위해 집계 테이블을 생성하는 것을 고려할 수 있습니다.  집계 테이블을 생성하고 데이터베이스 사용량이 적은 새벽 시간에 배치를 수행하면 사용량이 많은 peek 시간에 데이터 집계 쿼리로 인한 부하를 피할 수 있게 됩니다.

  그리고 거래 내역 등 크기가 큰 테이블에 파티션이 적용되지 않았거나 파티션 키가 잘못 정의된 경우도 조심스럽게 모델 변경을 고려 할 수도 있습니다.
  이런 규모의 테이블은 시스템 내에서 활용도가 높을 수 있으므로, 단순한 테이블 변경으로 작업을 마무리 할 수는 없을 것입니다.
  테이블이 변경되면 테이블과 관련된 SQL의 모든 실행 계획이 변경될 가능성이 큽니다. 어제까지만해도 잘 수행되던 쿼리가 테이블 변경으로 순식간에 악성쿼리로 변경될 가능성이 있기 때문입니다.
  또한 기존의 데이터도 유지해야 하므로 이전 테이블에서 변경된 테이블로 데이터를 이관하는 작업도 필요합니다.

  따라서, 이러한 대용량의 테이블의 구조를 변경하기 위해서는 사전 작업이 필요합니다. 우선 임시 테이블에 데이터를 적재하여 쿼리 테스트를 진행해야 합니다. 기존의 쿼리를 테스트하여 실행 계획 상에 문제가 없는지 확인이 필요합니다. 쿼리상의 문제가 없음이 확인된 후에야 현행 데이터 이관까지 포함된 테이블 변경작업을 진행할 수 있습니다. 추가로 테이블 통계 정보를 생성하거나 기존 테이블에서 데이터를 이관하는 것도 잊지 말아야 합니다.

 

5. SQL 튜닝 (SQL tuning)

  운영중인 데이터베이스에서 성능 저하가 발생하였을 때, 성능 최적화를 위해 선택할 수 있는 가장 큰 대안은 SQL 튜닝일 것입니다. 위에서 언급한 것처럼 운영 중인 시스템의 모델을 변경하거나 인덱스를 추가/변경하는 작업은 영향도가 큰 작업이므로 실제로 적용할 수 있는 기회는 많지 않습니다.

  SQL을 튜닝하는 구체적인 방법은 아래와 같습니다.

 

1) Use hint

  옵티마이저가 항상 최적의 실행 계획을 제시하는 것은 아닙니다. 조인 대상 데이터 건수가 적은데 NL조인이 아닌 Hash 조인을 수행하거나, 엉뚱한 인덱스를 액세스하는 실행 계획이 수립 될 수도 있습니다.
  이런 경우 SQL에 힌트를 사용하여 쿼리의 실행계획을 변경할 수 있습니다.

  오라클에서 제공하는 주요 힌트는 아래와 같습니다.

힌트 설명
USE_NL(테이블) Nested Loops 조인을 유도합니다.
USE_HASH(테이블) Hash 조인을 유도합니다.
USE_MERGE(테이블) Sort Merge 조인을 유도합니다.
ORDERED  FROM에 명시된 테이블을 순서대로 액세스하도록 유도합니다.
LEADING(테이블) 명시된 테이블부터 액세스하도록 유도합니다.
INDEX(테이블 인덱스명) 테이블 액세스 시 지정 인덱스를 이용하도록 유도합니다.
NO_INDEX(테이블 인덱스명) 테이블 엑세스 시 지정 인덱스를 제외하도록 유도합니다.
FULL(테이블) 테이블 액세스 시 Full table scan을 유도합니다.
INDEX_RS(테이블 인덱스명) Index Range Scan을 유도합니다.
INDEX_SS(테이블 인덱스명) Index Skip Scan을 유도합니다.
INDEX_FFS(테이블 인덱스명) Index Fast Full Scan을 유도합니다.
UNNEST  서브 쿼리와 메인 쿼리를 합쳐 조인을 수행하도록 유도합니다.
NO_UNNEST 서브 쿼리를 유지한 상태에서 필터 방식으로 처리하도록 유도합니다.
MERGE 인라인 뷰를 풀어 메인 쿼리내 테이블과 조인으로 수행되도록 유도합니다.
NO_MERGE 뷰를 Merge하지 않고 인라인 뷰가 그대로 유지도록 유도합니다.
PARALLEL
쿼리를 병렬로 수행하도록 유도합니다.

 

2) Rewrite SQL

  누누히 얘기하지만 SQL의 성능 판단 기준은 실행 시간과 블럭 액세스 횟수입니다.

  위 기준으로 악성 쿼리를 검출해보면 데이터를 절차적으로 처리하도록 작성된 쿼리를 발견하기도 합니다. 동일한 테이블을 여러 번 액세스하거나, 데이터를 줄일 수 있는 부분을 놓치고 있는 경우가 있는거죠. 물론 개발 시간이 촉박한 상황에서는 절차적인 방식으로 쿼리를 작성하고 쿼리 수행 결과가 정상이면 바로 쿼리 작성을 완료하고 넘어가는 일이 비일비재하다는 것을 알고 있습니다. 이러한 상황적 한계로 SQL 튜너가 별도로 필요한 것이고요.

  아무튼 SQL 쿼리문은 집합적인 사고로 데이터 액세스를 최소화 할 수 있는 방법을 사용해 작성되어야 합니다. 절차적으로 작성된 쿼리문은 최대한 집합적 관점에서 다시 재작성이 필요합니다.

집합적 사고

  SQL 튜닝 예제는 아래 포스트를 참고 바랍니다. 

 

Oracle SQL 튜닝 예제 #1 - 집합적 사고 접근법

[ 튜닝 전 ] 아래 쿼리를 살펴보도록 하겠습니다. SELECT CNT1, CNT2, CNT3, CNT4, CNT5, CNT6, CNT7, CNT8 FROM ( SELECT (SELECT COUNT(*) FROM CHG_LOGS WHERE REG_DT=:B1 AND ST_CD='0' AND LOG_LVL='1') CNT..

sparkdia.tistory.com

 

 

3) Remove UDF

 위 4-2) View와 UDF 사용 최소화 (At least view and UDF)에서 언급했듯이 UDF는 쿼리문을 간결하게 만들어주지만, 잘못 사용되면 성능 부하의 큰 원인이 됩니다. UDF사용으로 성능 부하를 일으키는 SQL문은 당연히 해당 UDF를 제거하는 작업을 해야 합니다.

  구체적인 UDF 제거 방법은 위 "4-2) View와 UDF 사용 최소화 (At least view and UDF)"에서 링크한 포스트를 참고 바랍니다.

 

  감사합니다.

 

  테이블 조인 방식은 테이블의 각 로우를 매핑 시 어떤 메커니즘을 사용하느냐에 따라 조인을 구분하는 겁니다.

  데이터 셋의 건수 등을 기반으로 옵티마이져가 적합한 조인 메커니즘을 선택하여 실행 계획을 생성하게 됩니다. 이때, 테이블 통계정보의 오류 등으로 인하여 적합하지 않은 조인 방식이 선택될 수도 있습니다. 잘못 선택된 조인 방식은 때때로 성능상의 부하를 유발하게 됩니다.
  따라서, 각 조인 방식에 대한 메카니즘을 파악하여 조회 쿼리에 적합한 조인 방식이 선택되도록 유도하는 것이 데이터베이스 성능 향상을 위한 중요한 방법 중의 하나가 되겠습니다.

 

  오라클에서 제공하는 조인 방식(Join methods)은 아래와 같습니다.

Join Methods

 

1. NL(Nested Loops) 조인

  Nested Loops 조인(이하 NL 조인)을 한국어로 직역하면 '중첩 반복 조인'입니다. 뜻 그대로 거듭된 반복 작업으로 조인을 수행하는 방식이 바로 NL 조인입니다.

  NL 조인은 드라이빙 테이블*의 한 로우와 매칭되는 드리븐 테이블**내 로우를 찾기위해 드리븐 테이블의 모든 데이터를 탐색하고 조인 컬럼 값이 일치하는 경우 양쪽 테이블의 두 로우를 연결합니다. 드라이빙 테이블에서 조회 조건에 부합하는 로우가 여러 건인 경우에는 로우 수만큼 위 작업을 반복적으로 수행하여 조인을 완료하게 됩니다.

* 드라이빙 테이블(Driving table) : 조인 대상 테이블 중 먼저 액세스하는 테이블을 말하며 Outer table이라고도 표현 가능합니다.
** 드리븐 테이블(Driven-to table) : 조인 대상 테이블 중 나중에 액세스하는 테이블을 말하며 Inner table이라고도 표현 가능합니다.

  

1.1. NL 조인 작동 방식

  오라클 문서에서 슈도(pseudo) 코드로 표현한 NL 조인 로직은 아래와 같습니다. NL 조인과 중첩된 For loop 수행이 개념적으로 동일한 로직이라고 설명하고 있습니다. 

[출처] https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/joins.html


  우선 드라이빙 테이블(위 로직에서는 employees 테이블)에서 조건에 맞는 (where X=Y) 로우를 (바깥쪽, Outer) For문을 이용해 모두 추출하게 됩니다. 이때, 드라이빙 테이블에서 로우가 추출될 때마다 (안쪽, Inner) For문을 수행하게 됩니다. For문을 수행하면서 드리븐 테이블(위 로직에서는 departments 테이블)의 로우를 탐색하는데, 드라이빙 테이블의 조인 컬럼 값과 매칭 된다면 output에 조인 결과를 저장하게 됩니다.

  위 로직을 그림으로 표현하면 아래와 같습니다.

Nested Loops Join

  위에서 설명했듯이 NL 조인은 드라이빙 테이블에서 추출되는 데이터 건수만큼 드리븐 테이블을 반복해서 탐색하게 됩니다. 드라이빙 테이블에서 10건의 로우가 추출되면 드리븐 테이블을 10번 반복해서 액세스를 하게되고, 10만 건의 로우가 추출되면 드리븐 테이블을 10만 번 반복해서 액세스를 하게 됩니다.

  이와 같은 NL 조인의 특성 때문에 아래 조건을 충족해야만 NL 조인 시 좋은 성능을 보장 받을 수 있습니다.

  1) 조인 테이블 중 추출 건수가 적은 테이블을 드라이빙 테이블로 선정.
  드라이빙 테이블의 추출 건수가 곧 드리븐 테이블의 액세스 반복 횟수가 되므로 건수가 더 적은 테이블이 드라이빙 테이블로 선정되어야 합니다.     

  2) 드리븐 테이블에 조인 조건 컬럼으로 구성된 인덱스가 존재.
  드리븐 테이블은 드라이빙 테이블의 추출 건수만큼 반복해서 액세스하게 됩니다. 이때 조인 컬럼으로 구성된 인덱스가 존재한다면 드리븐 테이블의 모든 데이터를 액세스 하지 않아도 인덱스를 이용해 조인 조건에 맞는 로우를 추출할 수 있게 됩니다. 만약 조인 컬럼으로 구성된 인덱스가 존재하지 않는다면 Full table scan이 반복적으로 발생하여 성능상 이슈가 발생할 수 있습니다.

 

1.2. NL 조인 실행 계획

  아래 쿼리는 EMPLOYEES 테이블과 DEPARTMENTS 테이블을 조인하는 쿼리 예제입니다. 
  두 테이블의 조인 컬럼은 DEPARTMENT_ID이며, EMPOLYEES 테이블의 LAST_NAME이 'A'로 시작하는 데이터만 추출하고자 합니다. 
  EMPLOYEES 테이블에서 LAST_NAME이 'A'로 시작하는 데이터는 4건이며, DEPARTMENTS 테이블의 데이터 건수는 27건입니다.

SELECT E.EMPLOYEE_ID 
         , E.FIRST_NAME 
         , E.LAST_NAME 
         , D.DEPARTMENT_NAME 
    FROM EMPLOYEES E 
         , DEPARTMENTS D 
 WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID 
     AND E.LAST_NAME LIKE 'A%' ;

위 쿼리의 실행 계획은 아래와 같습니다.

  1) 1차 Nested Loops ( Id = 2 )
    1-1) EMP_NAME_IX 인덱스를 탐색하여 "E.LAST_NAME LIKE 'A%'" 조건에 부합하는 rowid를 취득합니다. (Id = 4)
    1-2) 1-1)에서 얻은 rowid로 EMPLOYEES 테이블을 액세스하여 EMPLOYEE_ID와 DEPARTMENT_ID값을 취득합니다. (Id = 3)
    1-3) 1-2)의 데이터가 NL조인의 Outer가 됩니다. For문처럼 Outer의 로우를 하나씩 인출하여 DEPT_ID_PK 인덱스를 탐색하고 DEPATMENT_ID 값과 매칭 되는 rowid를 취득합니다. EMPLOYEES 테이블과 DEPARTMENTS 테이블의 인덱스와 NL조인을 하게 됩니다.  (id = 5,1)

  2) 2차 Nested Loops ( Id = 1 )
    2-1) 1-3)의 데이터가 NL 조인의 Outer가 됩니다. For문처럼 Outer의 로우를 하나씩 인출하여 rowid로  DEPARTMENTS 테이블에 액세스하여 DEPARTMENT_NAME 값을 취득합니다. (Id = 6,1)

 

 

2. 해시(Hash) 조인

  해시 조인은 조인 키 컬럼 값의 해시 함수 결과를 이용하여 조인하는 방식입니다. NL 조인과는 상대적으로 큰 데이터 셋을 조인하기 위한 방식입니다.

 

2.1. Hash 조인 작동 방식

  해시 조인에서도 조인 대상 테이블 중 크기가 더 작은 테이블부터 액세스 합니다.
  해시 조인에서는 먼저 액세스 하는 테이블을 빌드(Build) 테이블, 나중에 액세스 하는 테이블은 프로브(Probe) 테이블이라고 부릅니다.

   빌드 테이블을 읽어 각 로우의 조인 키 컬럼 값을 해시 함수에 대입합니다. 
  ② 해시 함수의 결과 값을 이용해 메모리(PGA)에 해시 테이블을 생성합니다. 해시 함수 결과 값은 해시 테이블에서 각 로우가 저장된 슬롯의 위치를 나타냅니다. 만약, 조인 키 컬럼 값이 상이하지만 동일한 해시 함수 결과 값이 나온 로우는 동일한 슬롯(Slot)에 저장되며 각 데이터는 링크드 리스트로 연결됩니다.

Hash join

  ③ 빌드 테이블의 모든 로우가 해시 테이블에 저장이 완료되면, 프로브 테이블의 데이터를 한 로우씩 읽기 시작합니다. 프로브 테이블도 빌드 테이블과 마찬가지로 조인 키 컬럼 값을 ②에서 사용된 동일한 해시 함수에 입력하여 결과 값을 계산합니다.
  ④ 계산된 해시 함수 결과 값을 이용해 해시 테이블 내 관련된(해시 결과 값이 동일한) 슬롯을 찾아갑니다. 만약, 해시 결과 값이 동일한 슬롯이 없다면 조인에 실패한 로우이므로 프로브 테이블의 다음 로우를 읽어 조인 연산을 계속 진행합니다.
  ⑤ 해시 결과 값으로 관련 슬롯을 찾았으면 슬롯 안에 저장된 빌드 테이블의 로우를 확인합니다. 로우의 조인 컬럼 값이 프로브 테이블 로우의 조인 컬럼 값과 일치하면 두 로우를 매핑하여 결과 셋(Result set)에 저장합니다. 슬롯 내에는 동일한 조인 컬럼 값을 가진 로우가 여러 건 존재할 수 있으므로 슬롯 내 링크드 리스트를 끝까지 탐색하여 조인을 완료합니다.

 

  해시 조인에서는 아래 조건을 충족하는 경우 좋은 성능을 보장 받을 수 있습니다.

  1) 조인 테이블 중 추출 건수가 적은 테이블을 빌드 테이블로 선정.
    조인을 위해 빌드 테이블의 데이터는 PGA 메모리의 해시 테이블에 저장됩니다. 해시 테이블의 크기가 커서 PGA 메모리가 부족해지면 가상 메모리를 사용하기 떄문에 DISK I/O가 발생하게 됩니다. 따라서, 데이터 건수가 적은 테이블이 빌드 테이블로 선정되어야 하며, 쿼리문 상에 결과 셋에 저장될 컬럼명만 명시하여 해시 테이블의 크기를 최소화해야 합니다.

  2) 프로브 테이블은 Full table scan이 유리.
    일반적으로 해시 조인에서 프로브 테이블은 대용량의 테이블입니다. 만약 인덱스를 이용해 프로브 테이블을 액세스하면 테이블 랜덤 액세스가 과도하게 발생하여 블록 I/O가 증가하게 됩니다. 테이블 액세스 없이 INDEX SCAN만으로 데이터 추출이 가능한 경우는 제외하고, 되도록이면 인덱스 스캔 없이 테이블만 스캔하여 블럭 I/O를 줄여야 합니다.

 

  참고로, 오라클 문서에서 슈도(pseudo) 코드로 표현한 해시 조인 로직은 아래와 같습니다.

[출처] https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/joins.html
[출처] https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/joins.html

 

2.2. Hash 조인 실행 계획

  아래 쿼리는 PROD 테이블과 PROD_SALE 테이블을 조인하는 쿼리 예제이며, 조인 컬럼은 PROD_NO입니다. PROD 테이블의 전체 테이블 건수는 71,734건입니다. PROD_SALE 테이블은 SALE_DT 컬럼으로 파티셔닝 되어 있으며, SALE_DT = '20191231'인 데이터 건수는 287,290건으로 대용량 테이블입니다.

SELECT S.SALE_DT
           , P.PROD_NM
           , S.PROD_QTY 
  FROM PROD P
           , PROD_SALE S 
 WHERE P.PROD_NO = S.PROD_NO 
     AND S.SALE_DT = '20191231' ;

  위 쿼리의 실행 계획은 아래와 같습니다.

  1) 두 테이블 중에서 크기가 작은 PROD 테이블이 빌드 테이블이 되며, FULL TABLE SCAN을 하게 됩니다. PROD 테이블의 각 ROW를 읽으면서 조인 칼럼의 값인 PROD_NO 값을 해시 함수에 대입한 결과 값으로 해시 테이블을 메모리에 생성합니다. (Id = 2)

  2) 해시 테이블 생성이 완료되면 프로브 테이블인 PROD_SALE 테이블을 FULL TABLE SCAN하기 시작합니다.(Id = 4) PROD_SALE 테이블은Where 절의 파티션 컬럼 필터링 조건으로 인하여 하나의 파티션만 액세스 하게 됩니다.(Id = 3)

  3) PROD_SALE 테이블의 로우를 하나씩 읽으면서 조인 컬럼 값인 PROD_NO 값을 해시 함수에 대입한 결과 값으로 해시 테이블 내 관련 슬롯을 찾아가게 됩니다. 슬롯에 저장된 빌드 테이블의 데이터와 조인 키 칼럼 값을 비교하면서 컬럼 값이 일치하는 데이터와 매핑하여 조인을 완료하게 됩니다. (Id = 1)

 

3. 소트 머지(Sort Merge) 조인

  소트 머지 조인은 조인 대상 테이블 데이터의 조인 키 컬럼 값을 기준으로 각 데이터 셋을 정렬한 후 작은 값부터 양쪽의 조인 키 컬럼 값이 매칭 되는지 확인하여 조인하는 방법입니다.

[출처] https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/joins.html

  오라클의 옵티마이저는 조인 조건이 동등 조건(=)이 아니거나(해시 조인은 동등 조건만 가능) 인덱스 사용으로 정렬 작업을 생략 할 수 있는 경우에 해시 조인 대신 소트 머지 조인을 선택합니다.
  또한, 해시 조인에서 해시 테이블이 너무 커서 PGA 메모리 부족으로 가상 메모리(디스크)를 사용하게 되면 디스크 I/O가 빈번하게 발생하게 됩니다. 프로브 테이블의 조인 키 칼럼 값은 정렬된 상태가 아니기 때문에 해시 테이블의 블록을 여러 번 읽어야 할 수도 있습니다. 하지만 소트 머지 조인은 조인 키 컬럼 값이 정렬된 상태이기 때문에 가상 디스크를 사용하더라도 디스크 I/O 횟수가 해시에 비해 훨씬 적다는 장점이 있습니다.

 

 3.1. Sort Merge조인 작동 방식

  소트 머지 조인을 수행하기 위해서 각 조인 대상 테이블은 조인 키 컬럼 기준으로 정렬되어 메모리(PGA)에 저장됩니다.

  정렬된 첫 번째 데이터 셋에서 첫 번째 로우를 읽어 조인 키 컬럼 값이 두 번째 데이터 셋에 존재하는지 확인합니다. 
  만약, 매칭되는 조인 키 컬럼 값이 두 번째 데이터 셋에 존재하지 않는다면 첫 번째 데이터 셋을 순차적으로 읽어 먼저 읽은 로우의 칼럼 값 보다 큰 로우의 컬럼 값을 찾습니다. 

  위 그림에서 첫 번째 데이터 셋의  '10'은 두 번째 데이터 셋의 첫 번째 값인 '20'보다 작은 값이므로 매칭되는 로우가 없으므로 첫 번째 데이터 셋의 '10' 다음의 값인 '20'을 읽게 됩니다.

  두 번째 테이블에서 아직 탐색이 진행되지 않았으므로 첫 번째 컬럼 값부터 데이터를 읽습니다. 이 값이 첫 번째 데이터 셋에서 읽은 값 '20'과 동일하다면 해당 값보다 큰 데이터가 나올 때까지 두 번째 데이터 셋을 읽어 나가면서 매칭 된 데이터를 결과 셋에 저장하게 됩니다. 
  두 번째 테이블에서 '20'보다 큰 값을 발견하면 해당 로우의 위치를 기억해놓고 첫 번째 테이블로 돌아가 다음 로우를 읽습니다. 로우 값 '30'을 읽어 두 번째 테이블에서 마지막 탐색 위치의 값과 비교합니다. 두 번째 테이블의 값도 '30'이므로 두 데이터를 결과 셋에 저장합니다. 마찬가지로 두 번째 테이블에서의 탐색을 계속 진행하는데 다음 로우의 값은 '30'보다 크므로 탐색을 중지하고 다시 첫 번째 데이터셋으로 돌아가 다음 로우를 읽습니다.

  첫 번째 데이터 셋의 다음 로우의 값 '40'은 두 번째 데이터 셋의 마지막 탐색 로우의 값인 '50'보다 작으므로 매칭 되는 로우가 없는 것입니다.
  다시 첫 번째 데이터 셋의 다음 로우인 '50'을 읽습니다. 두 번째 데이터 셋의 마지막 탐색 로우의 값인 '50'과 동일하므로 두 번째 데이터 셋을 계속 탐색하면서 매칭되는 데이터를 결과 셋에 저장하게 됩니다.
  두 데이터 셋의 탐색이 종료되면 조인 작업이 완료된 것입니다.

 

참고로, 오라클 문서에서 슈도(pseudo) 코드로 표현한 소트 머지 조인 로직은 아래와 같습니다.

[출처] https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/joins.html

 

3.2. Sort Merge조인 실행 계획

  아래 쿼리는 EMPLOYEES 테이블과 DEPARTMENTS 테이블을 DEPARTMENT_ID 조인 키 컬럼 기준으로 조인하는 쿼리 예제입니다. 두 테이블을 인덱스 사용 없이 Full table scan을 하기 위해 NO_INDEX 힌트를 사용하였으며, 소트 머지 조인을 하기 위해 USE_MERGE 힌트를 사용하였습니다.

SELECT /*+ USE_MERGE(d e) NO_INDEX(e) NO_INDEX(d) */ 
           D.DEPARTMENT_NAME 
         , E.FIRST_NAME 
         , E.LAST_NAME 
   FROM EMPLOYEES E 
         , DEPARTMENTS D 
 WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID ;

  위 쿼리의 실행 계획은 아래와 같습니다.

  1) 첫 번째 테이블 DEPARTMENTS 테이블을 Full table scan 하여 조인 키 컬럼 기준으로 정렬하는 Sort join 작업을 진행합니다. ( Id = 3,2 )

  2) 두 번째 테이블 EMPLOYEES 테이블도 Full table scan하여 조인 키 컬럼 기준으로 정렬하는 Sort join 작업을 진행합니다. ( Id = 5,4 )

  3) 정렬된 키 컬럼 값을 순차적으로 읽어 두 테이블 양쪽 모두에 조인 컬럼 키 값이 존재하면 매핑하여 데이터 결과 셋에 추가합니다. ( Id = 1 )

 

  이상으로 조인 방식에 대해 설명드렸습니다.

  참고로 데이터베이스에서 조인을 구분하는 방법은 위에서 언급한 조인 방식 외에 조인 종류도 존재합니다.
  우리가 쿼리 작성 시 사용하는 Inner join, Outer join 등의 문법으로 구분하는 조인 방법입니다. (깊게 살펴보면 한 쪽 테이블에만 존재하는 데이터 출력 방법이라고 설명할 수 있습니다.)

  조인 종류에 대해서는 아래 포스트를 참고하시면 됩니다.

 

테이블 조인 종류(Table Join Type)

데이터베이스에서 데이터는 다수의 테이블에 나뉘어 저장되어 있습니다. 데이터의 중복을 제거하고 무결성을 보장하기 위해서 데이터 성격에 따라 분류하여 테이블에 저장을 하는 겁니다. 이렇게 테이블별로 분리..

sparkdia.tistory.com

 

 

  데이터베이스에서 데이터는 다수의 테이블에 나뉘어 저장되어 있습니다. 데이터의 중복을 제거하고 무결성을 보장하기 위해서 데이터 성격에 따라 분류하여 테이블에 저장을 하는 겁니다.
  이렇게 테이블별로 분리되어 있는 데이터를 연결하여 하나의 결과 데이터 셋으로 출력해야 할 때가 반드시 존재합니다. 이럴때 사용하는 것이 조인(Join)입니다. 

  기본적인 조인문 사용 방법은 아래와 같습니다.

ANSI-SQL ORACLE SQL
SELECT e.LAST_NAME 
          , d.DEPARTMENT_NAME 
  FROM EMPLOYEES e  
   JOIN DEPARTMENTS d 
      ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;
SELECT e.LAST_NAME
          , d.DEPARTMENT_NAME
  FROM EMPLOYEES e
          , DEPARTMENTS d
 WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID
;

  위 예제에서는 EMPLOYEES 테이블과 DEPARTMENTS 테이블을 조인하고 있습니다. 여기서 조인 조건은 양쪽 테이블의 조인 키 컬럼인 DEPARTMENT_ID 컬럼 값이 동일한 경우이며, EMPLOYEES 테이블의 LAST_NAME 컬럼과 DEPARTMENTS 테이블의 DEPARTMENT_NAME 컬럼의 값이 결과로 출력됩니다.

  위 예제와 같이 두 개의 테이블을 조인하기 위해서는 각 테이블에 조인 키로 사용 할 수 있는 컬럼이 존재해야 합니다. 두 테이블 간의 연결고리인 조인 키 컬럼을 사용해 테이블 내 각 데이터들의 짝꿍을 찾아갈 수 있게 됩니다.
  ( 물론 조인 조건절을 생략하여 한 로우와 상대쪽 테이블의 모든 로우를 매핑시키는 Cartesian join도 존재합니다. 하지만 이 포스트에서는 기본 조인 조건인 등호 기호(=)를 이용한 동등 조인(equi-join)을 기준으로 설명하겠습니다. )

  그런데 이 조인 키 컬럼의 값이 양 쪽 테이블에 모두 존재하는 것이 아니라 한쪽 테이블에만 존재하는 경우(짝꿍이 없는 경우)가 발생할 수 있습니다.
  '상품' 테이블과 '고객주문상품' 테이블을 예로 들어보겠습니다.
  신규 상품인 망고(상품ID : 4)가 '상품' 테이블에 입력되었습니다. 하지만 신규 상품인 망고의 고객 주문이 발생하지 않는다면, '고객주문상품' 테이블에는 망고의 상품ID 값 '4'가 존재할 수 없습니다. 상품ID '4'는 오직 '상품' 테이블에만 존재하게 됩니다.

  이런 경우에 짝궁이 없는 데이터를 출력 결과에 포함할 수도 있고 제외할 수도 있습니다. 
  바꿔서 말하면 우리가 어떤 조인 종류를 선택함에 출력 결과가 달라질 수 있습니다. 

  우리가 수학시간에 배웠던 집합의 종류를 생각해보면 이해가 더 쉬워질 수 있습니다.
  데이터 집합 A와 B가 존재하는 경우, 결과 데이터 집합은 다양한 집합 연산으로 추출할 수 있습니다. 전체 데이터 집합을 추출하기 위해 합집합( A ∪ B ) 연산을 할 수 있고요. 공통인 데이터 집합을 추출하기 위해 교집합( A ∩ B ) 연산을 할 수도 있습니다. 이렇듯 집합 연산에 따라 결과 데이터 집합은 달라지게 됩니다.

  그럼, 조인 종류(Join Type)에 대해 자세히 살펴보겠습니다. 대표적인 조인 종류는 아래와 같이 4가지가 존재합니다.

1. Inner join

  Inner join은 교집합( A ∩ B ) 연산과 같습니다. 조인 키 컬럼 값이 양쪽 테이블 데이터 집합에서 공통적으로 존재하는 데이터만 조인해서 결과 데이터 집합으로 추출하게 됩니다.

  Inner join 구문은 아래와 같습니다.

ANSI-SQL ORACLE SQL
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A  
[INNER] JOIN 테이블B 
    ON 테이블A.조인키컬럼 = 테이블B.조인키컬럼
;
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A 
           , 테이블B
 WHERE 테이블A.조인키컬럼 = 테이블B.조인키컬럼
;

  위 ANSI-SQL 구문에서 'INNER' 키워드는 생략이 가능합니다. 우리가 일반적으로 사용하는 조인문( 'JOIN' 키워드만 사용하는 구문)이 바로 Inner join 구문입니다.

 

  아래는 조인 종류를 설명할 예제 데이터입니다. 

[예제 1] 상품과 고객주문상품 테이블 데이터

  고객주문상품 테이블의 상품ID가 '5'인 데이터는 부모 테이블인 상품 테이블에 존재하지 않는 값으로 FK 위반입니다. 하지만, OUTER JOIN의 예를 설명하기 위한 억지스러운 설정일 뿐입니다. 무결성에 위배되는 데이터지만 설명을 위해 이해 부탁드립니다.

  위 [예제 1] 상품 테이블과 고객주문상품 테이블을 Inner join하는 예제를 살펴보겠습니다.

-- ANSI-SQL
SQL> SELECT p.상품ID, p.상품명, o.상품ID, o.고객ID, o.주문일자, o.주문수량
    2>   FROM 상품 p
    3>    JOIN 고객주문상품 o
    4>        ON p.상품ID = o.상품ID;

 

  Inner join의 결과는 아래와 같습니다.

  상품 테이블과 고객주문상품에서 조인 키 컬럼 값이 모두 존재하는 데이터만 출력된 것을 확인하실 수 있습니다.

 

 

2. Left outer join

  Left outer join은 교집합 연산 결과와 차집합 연산 결과를 합친 것( (A  B) (A - B) )과 같습니다.
  조인 키 컬럼 값이 양쪽 테이블 데이터 집합에서 공통적으로 존재하는 데이터와 
Left outer join 키워드 왼쪽에 명시된 테이블에만 존재하는 데이터를 결과 데이터 집합으로 추출하게 됩니다.

  Left outer join 구문은 아래와 같습니다.

ANSI-SQL ORACLE SQL
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A  
   LEFT OUTER JOIN 테이블B 
      ON 테이블A.조인키컬럼 = 테이블B.조인키컬럼
;
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A 
            , 테이블B
 WHERE 테이블A.조인키컬럼 = 테이블B.조인키컬럼(+)
;

  ANSI-SQL 구문에서는 FROM 절에 조인하고자 하는 두 테이블명 사이에 'LEFT OUTER JOIN' 키워드를 입력합니다.
  ORACLE에서는 WHERE 절에서 오른쪽 테이블의 조인 키 컬럼명 뒤에 '(+)' 기호를 입력해줍니다.

  위 [예제 1] 상품 테이블과 고객주문상품 테이블을 Left outer join 하는 예제를 살펴보겠습니다.

-- ANSI-SQL
SQL> SELECT p.상품ID, p.상품명, o.상품ID, o.고객ID, o.주문일자, o.주문수량
    2>    FROM 상품 p
    3>     LEFT OUTER JOIN 고객주문상품 o
    4>        ON p.상품ID = o.상품ID;

   조인하고자 하는 테이블명을 LEFT OUTER JOIN 키워드를 기준으로 양쪽에 입력하고, 조인 조건은 ON 키워드 다음에 작성해줍니다.

-- ORACLE SQL
SQL> SELECT p.상품ID, p.상품명, o.상품ID, o.고객ID, o.주문일자, o.주문수량
    2>   FROM 상품 p
    3>             , 고객주문상품 o
    4>  WHERE p.상품ID = o.상품ID(+);

  Oracle에서는 FROM 키워드 이후에 조인할 테이블명을 콤마(,)로 구분하여 나열해주고, WHERE절에 조인 조건을 작성하되, 오른쪽 테이블의 조인 키 컬럼명 뒤에 '(+)' 기호를 추가로 입력해줍니다.

  Left outer join의 결과는 아래와 같습니다.

  상품 테이블과 고객주문상품에서 조인 키 컬럼 값이 모두 존재하는 데이터와 왼쪽에 명시되었던 테이블의 상품 테이블에만 존재하는 데이터(상품ID가 4인 데이터)가 출력된 것을 확인하실 수 있습니다.
  왼쪽 상품 테이블에만 데이터가 존재하는 로우의 오른쪽 고객주문상품 테이블 컬럼 값은 NULL로 표시됩니다.

 

 

3. Right outer join

 Right outer join도 교집합 연산 결과와 차집합 연산 결과를 합친 것( (A  B)  (A - B) )과 같습니다. 차집합의 기준 집합이 Left outer join과 반대일 뿐입니다.
  아무튼 조인 키 컬럼 값이 양쪽 테이블 데이터 집합에서 공통적으로 존재하는 데이터와 
Right outer join 키워드 오른쪽에 명시된 테이블에만 존재하는 데이터를 결과 데이터 집합으로 추출하게 됩니다.

  Right outer join 구문은 아래와 같습니다.

ANSI-SQL ORACLE SQL
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A  
RIGHT OUTER JOIN 테이블B 
      ON 테이블A.조인키컬럼 = 테이블B.조인키컬럼
;
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A 
           , 테이블B
 WHERE 테이블A.조인키컬럼(+) = 테이블B.조인키컬럼
;

  ANSI-SQL 구문에서는 FROM 절에 조인하고자 하는 두 테이블명 사이에 'RIGHT OUTER JOIN' 키워드를 입력합니다.
  ORACLE에서는 WHERE 절에서 왼쪽 테이블의 조인 키 컬럼명 뒤에 '(+)' 기호를 입력해줍니다.

  위 [예제 1] 상품 테이블과 고객주문상품 테이블을 Right outer join 하는 예제를 살펴보겠습니다.

-- ANSI-SQL
SQL> SELECT p.상품ID, p.상품명, o.상품ID, o.고객ID, o.주문일자, o.주문수량
    2>    FROM 상품 p
    3>   RIGHT OUTER JOIN 고객주문상품 o
    4>        ON p.상품ID = o.상품ID;

   조인하고자 하는 테이블명을 RIGHT OUTER JOIN 키워드를 기준으로 양쪽에 입력하고, 조인 조건은 ON 키워드 다음에 작성해줍니다.

-- ORACLE SQL
SQL> SELECT p.상품ID, p.상품명, o.상품ID, o.고객ID, o.주문일자, o.주문수량
    2>   FROM 상품 p
    3>            , 고객주문상품 o
    4>  WHERE p.상품ID(+) = o.상품ID;

  Oracle에서는 FROM 키워드 이후에 조인할 테이블명을 콤마(,)로 구분하여 나열해주고, WHERE절에 조인 조건을 작성하되, 왼쪽 테이블의 조인 키 컬럼명 뒤에 '(+)' 기호를 추가로 입력해줍니다.

  Right outer join의 결과는 아래와 같습니다.

  상품 테이블과 고객주문상품에서 조인 키 컬럼 값이 모두 존재하는 데이터와 오른쪽에 명시되었던 테이블의 고객주문상품 테이블에만 존재하는 데이터(상품ID가 5인 데이터)가 출력된 것을 확인하실 수 있습니다.
  오른쪽 고객주문상품 테이블에만 데이터가 존재하는 로우의 왼쪽 상품 테이블 컬럼 값은 NULL로 표시됩니다.

 

 

4. Full outer join

  Full outer join은집합 연산 결과와 같습니다. 
  조인 키 컬럼 값이 양쪽 테이블 데이터 집합에서 공통적으로 존재하는 데이터와 한쪽 테이블에만 존재하는
데이터도 모두 결과 데이터 집합으로 추출하게 됩니다.

  Full outer join 구문은 아래와 같습니다.

ANSI-SQL ORACLE SQL
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A  
  FULL OUTER JOIN 테이블B 
        ON 테이블A.조인키컬럼 = 테이블B.조인키컬럼
;
SELECT 컬럼명 [, 컬럼명]
  FROM 테이블A  
  FULL OUTER JOIN 테이블B 
       ON 테이블A.조인키컬럼 = 테이블B.조인키컬럼
;

  ANSI-SQL 구문에서는 FROM 절에 조인하고자 하는 두 테이블명 사이에 'FULL OUTER JOIN' 키워드를 입력합니다.
  ORACLE에서 '(+)' 기호를 이용한 Full outer join은 지원하고 있지 않습니다. Full outer join은 ANSI-SQL 구문 형식과 동일하게 사용하면 됩니다.

  위 [예제 1] 상품 테이블과 고객주문상품 테이블을 Right outer join 하는 예제를 살펴보겠습니다.

-- ANSI-SQL & ORACLE SQL
SQL> SELECT p.상품ID, p.상품명, o.상품ID, o.고객ID, o.주문일자, o.주문수량
    2>    FROM 상품 p
    3>     FULL OUTER JOIN 고객주문상품 o
    4>        ON p.상품ID = o.상품ID;

   조인하고자 하는 테이블명을 FULL OUTER JOIN 키워드를 기준으로 양쪽에 입력하고, 조인 조건은 ON 키워드 다음에 작성해줍니다.

  Full outer join의 결과는 아래와 같습니다.

  상품 테이블과 고객주문상품에서 조인 키 컬럼 값이 모두 존재하는 데이터와 상품 및 고객주문상품 테이블에만 존재하는 데이터(상품ID가 4,5인 데이터)가 출력된 것을 확인하실 수 있습니다.
  왼쪽 상품 테이블에만 데이터가 존재하는 로우의 오른쪽 고객주문상품 테이블 컬럼 값은 NULL로, 오른쪽 고객주문상품 테이블에만 데이터가 존재하는 로우의 왼쪽 상품 테이블 컬럼 값도 NULL로 출력됩니다.

 

  이상으로 조인의 종류에 대해 알아봤습니다.

  다음 포스트에서는 조인 방식(Methods)에 대해 설명드리도록 하겠습니다.
  조인 종류는 한쪽 테이블에만 존재하는 로우의 출력 여부를 기준으로 조인을 구분한 것이라면,
  조인 방식은 각 로우를 매핑을 하는 매커니즘에 따라 조인을 구분한다고 보시면 됩니다.
  더 자세한 내용은 아래 포스트를 참고해주세요.

 

테이블 조인 방식(Table join method)

테이블 조인 방식은 테이블의 각 로우를 매핑 시 어떤 메커니즘을 사용하느냐에 따라 조인을 구분하는 겁니다. 데이터 셋의 건수 등을 기반으로 옵티마이져가 적합한 조인 메커니즘을 선택하여 실행 계획을 생성하..

sparkdia.tistory.com

 

'Database' 카테고리의 다른 글

RDBMS 성능 최적화 전략  (0) 2020.04.09
SQL tuning 작업은 이제 불필요하다?  (0) 2020.03.16
Cassandra cqlsh 기본 사용법  (0) 2016.02.11
Cassandra 설치 2  (0) 2016.02.11
Cassandra 설치 1 - 사전 작업 (JDK, Python)  (0) 2016.02.11

+ Recent posts