출처: 업무에 바로 쓰는 SQL 튜닝 최적의 성능을 위한 MySQL/MariaDB 쿼리 작성과 튜닝 실습
구조적 차이
오라클 DB는 통합된 스토리지 하나를 공유(shared everything)하여 사용하는 방식이지만 MySQL은 물리적인 DB 서버 마다 독립적으로 스토리지를 할당(shared nothing)하여 구성한다.
오라클은 공유 스토리지를 사용하므로 사용자가 어느 DB 서버에 접속하여 SQL 문을 수행하더라도 같은 결과를 출력하거나 동일한 구문(SELECT, INSERT, DELETE, UPDATE)을 처리할 수 있다.
반면 MySQL은 독립적인 스토리지 할당에 기반을 두는 만큼 이중화를 위한 클러스터(cluster)나 복제(replication)구성으로 운영하더라도 보통은 마스터-슬레이브(master-slave) 구조(주-종 구조)가 대부분이다. 이때 마스터 노드는 쓰기/읽기 처리를 모두 수행할 수 있고 슬레이브 노드는 읽기 처리만 수행할 수 있다.
쿼리문이 수행하는 서비스의 위치를 파악하고 튜닝을 진행하면 물리적인 위치 특성이 내포된 쿼리 튜닝을 수행할 수 있다.
다음은 마스터-슬레이브 구조로 구축한 두 대의 MySQL 서버를 보여준다. 애플리케이션을 통해 쿼리 오프로딩(query offloading)이 적용되므로 마스터 노드에서는 UPDATE, INSERT, DELETE 문을 수행하고 슬레이브 노드에서는 SELECT 문을 수행한다.
지원 기능의 차이
MySQL은 대부분 중첩 루프 조인(nested loop join) 방식으로 조인을 수행한다.
Oracle에서는 중첩 루프 조인 방식뿐만 아니라 정렬 병합 조인(sort merge join)과 해시 조인(hash join) 방식도 제공한다.
MySQL은 주로 중첩 루프 조인 알고리즘만으로 풀리며, 필요한 DBMS를 설정해 사용할 수 있고, 상대적으로 낮은 메모리 사용으로 저사양 PC에서도 손쉽게 설치 및 개발할 수 있다.
SQL 구문 차이
NULL 대체
tab이라는 테이블에서 col1 열을 조회할 때 Null 이라는 값을 N/A라는 문자열로 대체하는 쿼리
IFNULL(열명, '대쳇값')
mysql> SELECT IFNULL(col1, 'N/A') col1 FROM tab;
페이징 처리
테이블에서 데이터를 불러올 경우 전체가 아닌 일부 분량만 제한적으로 가져올 때
LIMIT 숫자
mysql> SELECT col1 FROM tab LIMIT 5;
현재 날짜
MySQL에서 SYSDATE() 함수를 사용할 수 있으나 다수의 SYSDATE() 함수를 사용하면 함수의 호출 시점을 출력하는 특성으로 상이한 값이 출력된다. 그래서 보통 NOW() 함수를 사용한다.
NOW()
mysql> SELECT NOW() AS date;
조건문
MySQL에서는 일반적인 프로그래밍에서 사용하는 키워드인 IF 문과 CASE WHEN~THEN 문을 사용한다
IF (조건식, '참값', '거짓값')
mysql> SELECT IF(col1 = 'A', 'apple', '-') AS col1
날짜 형식
날짜 데이터를 원하는 형태로 변경하는 구문을 작성할 수 있다. MySQL에서는 DATE_FORMAT() 함수를 사용한다.
DATE_FORMAT(날짜열, '형식')
mysql> SELECT DATE_FORMAT(NOW(), '%Y%m%d %H%i%s') AS date;
자동 증갓값
신규 데이터가 지속해 생성될 때는 증가하는 순번을 자동으로 매기는 숫자형 값, 즉 자동 증갓값을 저장할 수 있다.
MariaDB 에서는 시퀸스(sequence)라는 오브젝트(object)를 활용한다. 한편 MySQL에서는 두가지 방법으로 증갓값을 저장한다. 첫 번째는 특정 열의 속성으로 자동 증가하는 값을 설정하는 auto_increment를 명시하는 방법이다. 두 번째는 오라클과 마찬가지로 시퀸스라는 오브젝트를 생성한 뒤 호출하여 활용하는 방법이다.
AUTO_INCREMENT
CREATE TABLE tab(
seq INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(20) NOT NULL);
MariaDB 10.3 이상
CREATE SEQUENCE [시퀸스명]
INCREMENT BY [증감숫자]
START WITH [시작숫자]
NOMINVALUE OR MINVALUE [최솟값]
NOMAXVALUE OR MAXVALUE [최댓값]
CYCLE OR NOCYCLE
CACHE OR NOCACHE
CREATE SEQUENCE MARIA_SEQ_SAMPLE
INCREMENT BY 1
START WITH 1
MINVALUE 1
MAXVALUE 999999999999
CYCLE
CACHE;
문자 결합
여러 개의 문자를 하나로 결합하여 조회할 때, CONCAT() 함수를 사용한다.
CONCAT(열값 또는 문자열, 열값 또는 문자열)
mysql> SELECT CONCAT('A', 'B') TEXT;
문자 추출
문자열에서 특정 구간 및 특정 위치의 문자열을 추출할 때, SUBSTRING() 함수를 사용한다.
ABCDE라는 문자열이 있다고 가정할 때 두 번째 위치의 문자(B)부터 시작해서 3개의 문자를 가져오는 쿼리
SUBSTRING(열값 또는 문자열, 시작 위치, 추출하려는 문자 개수)
mysql> SELECT SUBSTRING('ABCDE',2,3) AS sub_string;
MySQL과 MariaDB 튜닝의 중요성
MySQL과 MariaDB에는 다음과 같은 강점, 약점, 기회와 위험이 있다.
기본적으로 무료이고 경량화된 소프트웨어이므로 활용하기 편리하고 유용한 반면 수행 가능한 알고리즘이 적어서 성능적으로 불리하다. 대신 다양한 스토리지 엔진을 적극적으로 사용할 수 있는 기회가 존재한다.
따라서 이와 같은 SWOT 분석 결과에 따라 약점과 기회를 헤쳐나가기 외한 SQL 튜닝이 얼마나 중요한지 다시 한번 확인할 수 있다.