이 문서에서는 Oracle®과 MySQL용 Cloud SQL 사이의 기본적인 쿼리 차이를 설명하고 Oracle 기능이 MySQL용 Cloud SQL 기능과 어떻게 연결되는지 보여줍니다. 또한 MySQL용 Cloud SQL의 성능 고려 사항과 Google Cloud에서 쿼리 성능을 분석하고 최적화하는 방법을 살펴봅니다. 이 문서에서는 MySQL용 Cloud SQL을 위한 저장 프로시져 및 트리거를 최적화기 위한 기술을 설명하지만, PL/SQL 코드를 MySQL 저장 프로시져 및 함수로 변환하는 방법은 다루지 않습니다.
Oracle Database에서 MySQL용 Cloud SQL로 쿼리를 변환할 때는 SQL과 관련해서 몇 가지 언어적 차이를 고려해야 합니다. 또한 두 데이터베이스 플랫폼 간에는 서로 다르거나 호환되지 않는 몇 가지 기본 제공 함수가 존재합니다.
기본 쿼리 차이
Oracle과 MySQL용 Cloud SQL 모두 ANSI SQL을 지원하지만, 데이터를 쿼리할 때는 주로 시스템 함수 사용과 관련해서 몇 가지 기본적인 차이가 있습니다.
다음 표에서는 Oracle 및 MySQL용 Cloud SQL에 대한 SELECT
및 FROM
구문의 차이를 보여줍니다.
Oracle 기능 이름 | Oracle 구현 | MySQL용 Cloud SQL 지원 | MySQL용 Cloud SQL 상응 |
---|---|---|---|
데이터 검색을 위한 SQL 기본 구문 |
SELECT FROM WHERE GROUP BY HAVING ORDER BY
|
예 |
SELECT FROM WHERE GROUP BY HAVING ORDER BY
|
출력 인쇄를 위한 SELECT |
SELECT 1 FROM DUAL
|
예 |
SELECT 1 또는 SELECT 1 FROM DUAL
|
열 별칭 | SELECT COL1 AS C1
|
예 |
SELECT COL1 AS C1 또는 SELECT COL1 C1
|
테이블 이름 대소문자 구분 | 대소문자 구분 없음(예: orders 및 ORDERS 모두 테이블 이름으로 사용 가능) |
아니요 | 정의된 테이블 이름에 따라 대소문자 구분(예: orders 또는 ORDERS 만 테이블 이름으로 사용 가능) |
인라인 뷰
인라인 뷰(파생된 테이블이라고도 함)는 FROM
절에 있는 SELECT
문이며, 서브 쿼리로 사용됩니다. 인라인 뷰는 복합 계산을 없애거나 조인 연산을 제거하고, 여러 개별 쿼리를 간소화된 단일 쿼리로 압축하여 복잡한 쿼리를 간단하게 만드는 데 도움이 될 수 있습니다.
다음 예시에서는 인라인 뷰를 Oracle 11g/12c에서 MySQL용 Cloud SQL로 변환하는 예시를 보여줍니다.
Oracle 11g/12c의 인라인 뷰:
SELECT FIRST_NAME,
DEPARTMENT_ID,
SALARY,
DATE_COL
FROM EMPLOYEES,
(SELECT SYSDATE AS DATE_COL FROM DUAL);
MySQL용 Cloud SQL 5.7에서 사용되는 별칭 포함 뷰:
SELECT FIRST_NAME,
DEPARTMENT_ID,
SALARY,
DATE_COL
FROM EMPLOYEES, (SELECT SYSDATE() AS DATE_COL FROM DUAL) AS A1;
조인
Oracle의 join 유형은 FULL JOIN
을 제외하고 MySQL용 Cloud SQL에서 지원됩니다.
MySQL용 Cloud SQL 조인에서는 USING
절, ON
절 대신의 WHERE
절, JOIN
문의 SUBQUERY
와 같은 대체 구문 사용이 지원됩니다.
다음 표에서는 JOIN
변환 예시를 보여줍니다.
Oracle JOIN 유형 |
MySQL용 Cloud SQL 지원 | MySQL용 Cloud SQL JOIN 구문
|
---|---|---|
INNER JOIN |
예 |
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
|
CROSS JOIN |
예 |
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E CROSS JOIN DEPARTMENTS D
|
FULL JOIN |
아니요 | LEFT 및 RIGHT JOINS: 에 UNION 사용 고려
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
UNION
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E RIGHT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
|
LEFT JOIN
[ OUTER ]
|
예 |
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
|
RIGHT JOIN
[ OUTER ]
|
예 |
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E RIGHT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
|
SUBQUERY |
예 |
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E JOIN (SELECT * FROM DEPARTMENTS)D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
|
MySQL용 Cloud SQL이 UNION
및 UNION ALL
함수를 모두 지원하지만 Oracle의 INTERSECT
및 MINUS
함수를 지원하지 않습니다.
UNION
은 중복 레코드를 없앤 후 두SELECT
문의 결과 집합을 연결합니다.UNION ALL
은 중복 레코드를 없애지 않고 두SELECT
문의 결과 집합을 연결합니다.INTERSECT
는 두 쿼리의 결과 집합 모두에 레코드가 존재할 경우에만 두SELECT
문의 교집합을 반환합니다.MINUS
는 2개 이상의SELECT
문을 비교하고 두 번째 쿼리로 반환되지 않은 첫 번째 쿼리의 고유 행만 반환합니다.
다음 표에서는 Oracle에서 MySQL용 Cloud SQL로의 몇 가지 변환 예시를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 지원 | MySQL용 Cloud SQL 상응 |
---|---|---|---|
UNION |
SELECT COL1 FROM TBL1 UNION SELECT COL1 FROM TBL2
|
예 | SELECT COL1 FROM TBL1 UNION SELECT COL1 FROM TBL2
|
UNION ALL |
SELECT COL1 FROM TBL1 UNION ALL SELECT COL1 FROM TBL2
|
예 | SELECT COL1 FROM TBL1 UNION ALL SELECT COL1 FROM TBL2
|
INTERSECT |
SELECT COL1 FROM TBL1 INTERSECT SELECT COL1 FROM TBL2
|
아니요 |
SELECT COL1 FROM TBL1 WHERE COL1 IN (SELECT COL1 FROM TBL2)
|
MINUS |
SELECT COL1 FROM TBL1 MINUS SELECT COL1 FROM TBL2
|
아니요 | SELECT A.COL1
FROM TBL1 A LEFT JOIN TBL2 B
ON USING(COL1)
WHERE B.COL1 IS NULL
|
스칼라 및 그룹 함수
MySQL용 Cloud SQL은 광범위한 스칼라(단일 행) 및 집계 함수 목록을 제공합니다. 일부 MySQL용 Cloud SQL 함수는 해당 Oracle 함수와 비슷합니다. 여기에는 이름과 기능이 같은 경우도 있고 이름은 다르지만 기능이 비슷한 경우도 있습니다. 일부 MySQL용 Cloud SQL 함수는 해당 Oracle 함수와 이름이 같아도, 기능이 다를 수 있습니다.
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 문자 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
CONCAT |
첫 번째 문자열을 두 번째 문자열과 연결하여 반환합니다. CONCAT('A', 1) = A1
|
예 | CONCAT |
CONCAT('A', 1) = A1 |
CONCAT USING PIPE |
FNAME |' '| LNAME |
아니요 | CONCAT |
CONCAT(FNAME, ' ', LNAME) |
LOWER 또는 UPPER |
모든 문자를 소문자 또는 대문자로 바꿔서 문자열을 반환합니다.LOWER('SQL') = sql
|
예 | LOWER 또는 UPPER |
LOWER('SQL') = sql |
LPAD/RPAD |
n 문자 길이가 되도록 왼쪽 또는 오른쪽에 expression2 의 문자 시퀀스가 채워진 상태로 expression1 을 반환합니다.LPAD('A',3,'*') = **A
|
예 | LPAD 또는 RPAD |
LPAD('A',3,'*') = **A |
SUBSTR |
제공된 문자열에서 x 번째 위치(여기에서는 세 번째 문자)부터 시작하여 y 길이에 해당하는 부분을 반환합니다. 문자열의 첫 번째 위치는 1입니다.
SUBSTR('MySQL', 3, 3)
= SQL
|
예 | SUBSTR |
SUBSTR('MySQL', 3, 3)
= SQL
|
INSTR |
제공된 문자열에서 특정 문자열의 위치(색인)를 반환합니다.
INSTR('MySQL', 'y')
= 2
|
예 | INSTR |
INSTR('MySQL', 'y')
= 2
|
REPLACE |
검색어로 발견된 모든 문자열을 대체 문자열로 바꿔서 반환합니다.
REPLACE('ORADB', 'ORA', 'MySQL')
= MySQLDB
|
예 | REPLACE |
REPLACE('ORADB', 'ORA', 'MySQL')
= MySQLDB
|
TRIM |
문자열에서 선행 또는 후행 문자(또는 둘 다)를 자릅니다.
TRIM(both '-' FROM '-MySQL-')
= MySQL
TRIM(' MySQL ')
= MySQL
|
예 | TRIM |
TRIM(both '-' FROM '-MySQL-')
= MySQL
TRIM(' MySQL ')
= MySQL
|
LTRIM/RTRIM |
문자열의 왼쪽 또는 오른쪽에서 검색에 표시된 모든 문자를 삭제합니다.
LTRIM(' MySQL', ' ')
= MySQL
|
일부만 | LTRIM or RTRIM |
Oracle LTRIM 및 RTRIM 함수에는 문자열에서 삭제할 선행 또는 후행 문자를 지정하는 두 번째 매개변수가 사용됩니다. MySQL용 Cloud SQL 함수는 제공된 문자열에서 선행 및 후행 공백만 삭제합니다.
LTRIM(' MySQL')
= MySQL
|
ASCII |
단일 문자를 입력해서 해당 숫자 ASCII 코드를 반환합니다. ASCII('A') = 65
|
예 | ASCII |
ASCII('A') = 65 |
CHR |
0~225 사이의 숫자 값인 ASCII 코드 값을 해당 문자로 반환합니다.CHR(65) = A
|
다른 함수 이름 필요 | CHAR |
MySQL용 Cloud SQL에서는 동일 기능으로 CHAR 함수가 사용되므로, 함수 이름을 변경해야 합니다.CHAR(65) = A
|
LENGTH |
제공된 문자열의 길이를 반환합니다.LENGTH('MySQL') = 5
|
예 | LENGTH |
LENGTH('MySQL') = 5 |
REGEXP_REPLACE |
정규 표현식 패턴의 문자열을 검색합니다. REGEXP_REPLACE('John', '[hn].', 'e') = Joe
|
아니요 | 해당 없음 | MySQL 버전 8부터 지원됩니다. 이를 해결하기 위해서는 가능한 경우 REPLACE 함수를 사용하고, 아니면 논리를 애플리케이션 레이어로 이동합니다. |
REGEXP_SUBSTR |
정규 표현식 패턴에 대해 문자열을 검색하여 SUBSTR 함수의 기능을 확장합니다.
REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?')
=
https://console.cloud.google.com/
|
아니요 | 해당 없음 | MySQL 버전 8부터 지원됩니다. 이를 해결하기 위해서는 가능한 경우 SUBSTR 함수를 사용하고, 아니면 논리를 애플리케이션 레이어로 이동합니다. |
REGEXP_COUNT |
패턴이 소스 문자열에 있는 횟수를 반환합니다. | 아니요 | 해당 없음 | MySQL용 Cloud SQL에는 해당 함수가 없습니다. 이 논리를 애플리케이션 레이어로 이동하세요. |
REGEXP_INSTR |
정규 표현식 패턴에 대해 문자열 위치(색인)를 검색합니다. | 아니요 | 해당 없음 | MySQL 버전 8부터 지원됩니다. 이전 버전에서는 이 논리를 애플리케이션 레이어로 이동하세요. |
REVERSE |
제공된 문자열에 대해 예약된 문자열을 반환합니다.
REVERSE('MySQL')
= LQSyM
|
예 | REVERSE |
REVERSE('MySQL')
= LQSyM
|
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 숫자 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
ABS |
제공된 숫자의 절댓값을 반환합니다. ABS(-4.6) = 4.6 |
예 | ABS |
ABS(-4.6) = 4.6 |
CEIL |
제공된 숫자보다 크거나 같은 가장 작은 정수를 반환합니다. CEIL(21.4) = 22 |
예 | CEIL |
CEIL(21.4) = 22 |
FLOOR |
제공된 숫자보다 작거나 같은 가장 큰 정수를 반환합니다. FLOOR(-23.7) = -24
|
예 | FLOOR |
FLOOR(-23.7) = -24 |
MOD |
m 을 n 으로 나눈 나머지를 반환합니다.MOD(10, 3) = 1
|
예 | MOD |
MOD(10, 3) = 1 |
ROUND |
n 을 소수점 오른쪽 정수 자릿수로 반올림하여 반환합니다.ROUND(1.39, 1) = 1.4 |
예 | ROUND |
ROUND(1.39, 1) = 1.4 |
TRUNC (숫자) |
n1 을 n2 소수점 자릿수로 잘라서 반환합니다. 두 번째 매개변수는 선택사항입니다.
TRUNC(99.999) = 99
TRUNC(99.999, 0) = 99
|
다른 함수 이름 필요 | TRUNCATE (숫자) |
MySQL용 Cloud SQL 함수는 이름이 다르며, 두 번째 매개변수가 필수입니다. TRUNCATE(99.999, 0) = 99
|
다음 표에서는 Oracle 및 MySQL용 Cloud SQL datetime
함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
SYSDATE |
데이터베이스 서버가 있는 운영체제에 설정된 현재 날짜 및 시간을 반환합니다.
SELECT SYSDATE
FROM DUAL;
= 31-JUL-2019
|
예 | SYSDATE() |
MySQL용 Cloud SQL
SELECT SYSDATE()
FROM DUAL;
= 2019-01-31 10:01:01.0
|
SYSTIMESTAMP |
소수점 이하 초와 시간대를 포함하여 시스템 날짜를 반환합니다.
SELECT SYSTIMESTAMP FROM DUAL
= 01-JAN-19 07.37.11.622187000 AM +00:00
|
다른 함수 이름 필요 |
CURRENT_
TIMESTAMP
|
MySQL용 Cloud SQL은 기본적으로 다른 datetime 형식을 반환합니다. 출력 형식을 다시 지정하려면 DATE_FORMAT() 함수를 사용합니다.
SELECT CURRENT_TIMESTAMP
FROM DUAL;
= 2019-01-31 06:55:07
|
LOCAL_
TIMESTAMP
|
현재 날짜 및 시간을 TIMESTAMP 형식으로 반환합니다.
SELECT LOCALTIMESTAMP
FROM DUAL
= 01-JAN-19 10.01.10.123456 PM
|
다른 datetime 형식 반환 |
LOCAL_
TIMESTAMP
|
MySQL용 Cloud SQL은 Oracle 기본 형식과 다른 datetime 형식을 반환합니다. 출력 형식을 다시 지정하려면 DATE_FORMAT() 함수를 사용합니다.
SELECT LOCAL_TIMESTAMP
FROM DUAL
= 2019-01-01 10:01:01.0
|
CURRENT_DATE |
현재 날짜를 반환합니다.
SELECT CURRENT_DATE
FROM DUAL
= 31-JAN-19
|
다른 datetime 형식 반환 |
CURRENT_
DATE
|
MySQL용 Cloud SQL 함수는 다른 datetime 형식을 반환합니다. 출력 형식을 다시 지정하려면 DATE_FORMAT() 함수를 사용합니다.
SELECT CURRENT_DATE
FROM DUAL
= 2019-01-31
|
CURRENT_
TIMESTAMP
|
현재 날짜 및 시간을 반환합니다.
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 31-JAN-19 06.54.35.543146 AM +00:00
|
다른 datetime 형식 반환 |
CURRENT_
TIMESTAMP
|
MySQL용 Cloud SQL 함수는 다른 datetime 형식을 반환합니다. 출력 형식을 다시 지정하려면 DATE_FORMAT() 함수를 사용합니다.
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 2019-01-31 06:55:07
|
ADD_MONTHS |
날짜와 정수 월을 반환합니다.
ADD_MONTHS(SYSDATE, 1)
= 31-JAN-19
|
다른 함수 이름 필요 | ADDDATE |
MySQL용 Cloud SQL 함수는 다른 datetime 형식을 반환합니다. 출력 형식을 다시 지정하려면 DATE_FORMAT() 함수를 사용합니다.
ADDDATE(SYSDATE(), 1)
= 2019-08-01 06:42:49.0
|
EXTRACT (날짜 부분) |
간격 표현식을 기준으로 datetime 필드의 값을 반환합니다.
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
|
예 | EXTRACT (날짜 부분) |
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
|
LAST_DAY |
제공된 날짜의 월 중 마지막 일자를 반환합니다.
LAST_DAY('01-JAN-2019')
= 31-JAN-19
|
일부만 | LAST_DAY |
MySQL용 Cloud SQL은 Oracle 기본 형식과 다른 datetime 형식을 반환합니다. 출력 형식을 다시 지정하려면 DATE_FORMAT() 함수를 사용합니다.
LAST_DAY('2019-01-01')
= 2019-01-31
|
MONTH_
BETWEEN
|
제공된 날짜 date1 및 date2 :
MONTHS_BETWEEN(
SYSDATE, SYSDATE-60)
= 1.96
사이의 개월 수를 반환합니다.
|
일부만 |
PERIOD_DIFF
|
MySQL용 Cloud SQL PERIOD_DIFF 함수는 두 기간(YYMM 또는 YYYYMM 형식) 사이의 개월 수 차이를 정수 숫자로 반환합니다.
PERIOD_DIFF(
'201903', '201901')
= 2
|
TO_CHAR (Datetime) |
숫자, datetime , 타임스탬프 형식을 문자열 형식으로 변환합니다.
TO_CHAR(
SYSDATE,'DD-MM-YYYY HH24:MI:SS')
= 01-01-2019 10:01:01
|
다른 함수 이름 필요 | DATE_FORMAT |
MySQL용 Cloud SQL DATE_FORMAT 함수는 형식 문자열에 따라 날짜 값의 형식을 지정합니다.
DATE_FORMAT(
SYSDATE(),'%d-%m-%Y %H:%i:%s')
01-01-2019 10:01:01
|
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 인코딩 및 디코딩 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
DECODE |
IF-THEN-ELSE 문의 기능을 사용하여 표현식을 각 검색 값과 하나씩 비교합니다. |
아니요 | CASE |
비슷한 기능에 MySQL용 Cloud SQL CASE 문을 사용합니다. |
DUMP |
데이터 유형 코드, 바이트 길이, 내부 표현식 표현이 포함된 VARCHAR2 값을 반환합니다. |
아니요 | 해당 없음 | 지원되지 않음 |
ORA_HASH |
제공된 표현식의 해시 값을 계산합니다. | 아니요 | MD5 or SHA |
128비트 체크섬에는 MD5 함수를 사용하고 160비트 체크섬에는 SHA 함수를 사용합니다. |
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 변환 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
CAST |
기본 제공되는 한 가지 데이터 유형 또는 컬렉션 유형의 값을 다른 기본 제공되는 데이터 유형 또는 컬렉션 유형의 값으로 변환합니다.
CAST('1' as int) + 1
= 2
|
일부만 | CAST |
명시적 또는 암시적 변환이 필요한지에 따라 조정합니다.
CAST('1' AS SIGNED) + 1
= 2
|
CONVERT |
한 가지 문자 집합에서 다른 문자 집합으로 문자 문자열을 변환합니다.
CONVERT (
'Ä Ê Í Õ Ø A B C D E ', 'US7ASCII', 'WE8ISO8859P1')
= ?? ?? ?? A B C
|
일부만 | CONVERT |
MySQL용 Cloud SQL CONVERT 함수는 구문 및 매개변수에 따라 몇 가지 조정이 필요합니다.
CONVERT(
'Ä Ê Í A B C ' USING utf8)
= Ä Ê Í A B C
|
TO_CHAR (문자열/숫자) |
이 함수는 숫자 및 날짜를 문자열로 변환합니다.
TO_CHAR(22.73,'$99.9')
= $22.7
|
아니요 | FORMAT |
MySQL용 Cloud SQL FORMAT 함수는 숫자를 #,###,###.## 과 같은 형식으로 변환하고, 소수점 자릿수로 반올림한 후 결과를 문자열로 반환합니다.
CONCAT('$',
FORMAT(22.73, 1))
= $22.7
|
TO_DATE |
Oracle의 TO_DATE 함수는 datetimecode 형식을 기준으로 문자열을 날짜로 변환합니다.
TO_DATE(
'2019/01/01', 'yyyy-mm-dd')
= 01-JAN-2019
|
다른 함수 이름 필요 | STR_TO_DATE |
MySQL용 Cloud SQL STR_TO_DATE 함수는 문자열을 입력해서 datetime 형식을 기준으로 날짜를 반환합니다.
STR_TO_DATE(
'2019/01/01', '%Y/%m/%d')
= 2019-01-01
|
TO_NUMBER |
표현식을 NUMBER 데이터 유형의 값으로 변환합니다.
TO_NUMBER('01234')
= 1234
|
다른 함수 이름 필요 | CAST |
Oracle TO_NUMBER 함수와 동일한 결과를 반환하려면 MySQL용 Cloud SQL CAST 함수를 사용합니다.
CAST('01234' as SIGNED)
= 1234
|
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 조건부 SELECT
함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
CASE |
CASE 문은 일련의 조건을 선택하여 다음 구문으로 해당 문을 실행합니다.
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
|
예 | CASE |
CASE 함수 외에도 MySQL용 Cloud SQL는 SELECT 문 내에서 IF/ELSE 조건 처리 사용을 지원합니다.
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
|
다음 표에서는 Oracle 및 MySQL용 Cloud SQL null 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
COALESCE |
표현식 목록에서 null 아닌 첫 번째 표현식을 반환합니다.
COALESCE(
null, '1', 'a')
= a
|
예 | COALESCE |
COALESCE(
null, '1', 'a')
= 1
|
NULLIF |
expression1 과 expression2 사이의 비교를 수행합니다. 두 표현식이 동일하면 함수가 null 을 반환합니다.
서로 다르면 함수가 expression1 을 반환합니다.
NULLIF('1', '2')
= a
|
예 | NULLIF |
NULLIF('1', '2')
= a
|
NVL |
null 값을 쿼리 결과의 문자열로 바꿉니다.
NVL(null, 'a')
= a
|
아니요 | IFNULL |
IFNULL(null, 'a')
= a
|
NVL2 |
표현식이 null인지 아니면 null이 아닌지에 따라 쿼리로 반환되는 값을 결정합니다. | 아니요 | CASE |
CASE 문은 일련의 조건을 선택하여 해당 문을 실행합니다.
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
|
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 환경 및 식별자 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
SYS_GUID |
최대 16바이트로 구성된 전역 고유 식별자(RAW 값)를 생성하고 반환합니다.
SELECT SYS_GUID()
FROM DUAL
=
8EFA4A31468B4C6DE05011AC0200009E
|
아니요 | REPLACE 및 UUID |
이 문제를 해결하려면 REPLACE 및 UUID 함수를 사용하여 SYS_GUID 함수를 시뮬레이션합니다.
REPLACE(
UUID(), '-', '')
|
UID |
세션 사용자(로그온된 사용자)를 고유하게 식별하는 정수를 반환합니다.
SELECT UID FROM DUAL
= 43
|
아니요 | 해당 없음 | 해당 없음 |
USER |
현재 세션에 연결된 사용자의 사용자 이름을 반환합니다.
SELECT USER FROM DUAL
= username
|
예 | USER + INSTR + SUBSTR |
MySQL용 Cloud SQL USER 함수는 해당 연결에 대한 사용자 이름 및 호스트 이름(root@IP_ADDRESS )을 반환합니다. 사용자 이름만 검색하려면 추가적인 지원 함수를 사용합니다.
SELECT
SUBSTR(USER(), 1, INSTR(USER(), '@') -1) FROM DUAL
= root
|
USERENV |
세션 언어와 같은 현재 Oracle 세션에 대한 정보를 반환합니다.
SELECT USERENV('LANGUAGE')
FROM DUAL
= ENGLISH_AMERICA.
AL32UTF8
|
아니요 |
SHOW SESSION
VARIABLES
|
MySQL용 Cloud SQL SHOW SESSION VARIABLES 문은 현재 세션에 대한 문자열을 반환합니다.
SHOW SESSION VARIABLES LIKE '%collation%';
= utf8_general_ci
|
ROWID |
Oracle은 테이블에 있는 행을 식별하기 위해 테이블의 각 행에 고유한 ROWID 를 할당합니다. ROWID 는 데이터 객체 번호, 행의 데이터 블록, 행 위치, 데이터 파일이 포함된 행의 주소입니다. |
일부만 | 해당 없음 |
ROW_NUMBER() 는 MySQL 8.0부터 사용할 수 있습니다. 이전 버전을 사용 중이면 세션 변수 @row_number 를 사용하여 동일한 기능을 에뮬레이션합니다. |
ROWNUM |
Oracle 테이블에서 행이 반환되는 순서를 나타내는 숫자를 반환합니다. | 일부만 | 해당 없음 | ROW_NUMBER() 는 MySQL 8.0부터 사용할 수 있습니다. 이전 버전을 사용 중이면 세션 변수 @row_number 를 사용하여 동일한 기능을 에뮬레이션합니다. |
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 집계(그룹) 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
AVG |
열 또는 표현식의 평균 값을 반환합니다. | 예 | AVG |
Oracle과 동일 |
COUNT
|
쿼리로 반환된 행 수를 반환합니다. | 예 | COUNT |
Oracle과 동일 |
COUNT
(DISTINCT)
|
열 또는 표현식에 있는 고유 값 수를 반환합니다. | 예 |
COUNT
(DISTINCT)
|
Oracle과 동일 |
MAX |
열 또는 표현식의 최댓값을 반환합니다. | 예 | Oracle과 동일 | |
MIN |
열 또는 표현식의 최솟값을 반환합니다. | 예 | MIN |
Oracle과 동일 |
SUM |
열 또는 표현식의 값 합계를 반환합니다. | 예 | SUM |
Oracle과 동일 |
LISTAGG |
ORDER BY 절에 지정된 각 값으로 데이터 순서를 지정하고 측정 열의 값을 연결합니다.
SELECT LISTAGG(
DEPARTMENT_NAME, ', ')
WITHIN GROUP
(ORDER BY DEPARTMENT_NAME) DEPT
FROM DEPARTMENTS;
-- Single line results
= Accounting, Administration, Benefits, Construction
|
다른 함수 이름 및 구문 필요 |
GROUP_
CONCAT
|
동일한 결과를 반환하려면 MySQL용 Cloud SQL GROUP_CONCAT 함수를 사용합니다.
SELECT GROUP_CONCAT(
DEPARTMENT_NAME ORDER BY DEPARTMENT_NAME SEPARATOR ', ') DEPT
FROM DEPARTMENTS;
-- Single line results
= Accounting, Administration, Benefits, Construction
|
다음 표에서는 Oracle 및 MySQL용 Cloud SQL FETCH
함수의 이름 및 기능이 동일한 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 | MySQL용 Cloud SQL 구현 |
---|---|---|---|---|
FETCH |
다중 행 쿼리의 결과 집합에서 지정된 행 수를 검색합니다.
SELECT * FROM
EMPLOYEES
FETCH FIRST 10 ROWS ONLY;
|
예 | LIMIT |
쿼리에서 행을 검색하려면 MySQL LIMIT 절을 사용합니다.
SELECT * FROM
EMPLOYEES
LIMIT 10;
|
기본 필터링, 연산자, 서브 쿼리
기본 필터링, 연산자 함수, 서브 쿼리는 기본적인 작업만 수행해서 비교적 직관적으로 변환할 수 있습니다. Oracle 및 MySQL용 Cloud SQL에 사용되는 기본 날짜 형식이 다르기 때문에 대부분의 작업은 날짜 형식 변환과 관련됩니다.
- Oracle
SYSDATE
함수는 기본적으로01-AUG-19
형식을 반환합니다. - MySQL용 Cloud SQL
SYSDATE()
함수는 기본적으로2019-08-01 12:04:05
형식을 반환합니다.
날짜 및 시간 형식을 설정하려면 MySQL DATE_FORMAT
또는 STR_TO_DATE
함수를 사용합니다.
다음 표에서는 Oracle 및 MySQL용 Cloud SQL 기본 필터링, 연산자 및 서브 쿼리 함수의 이름 및 기능이 동일한 경우와 변환이 권장되는 경우를 보여줍니다.
Oracle 함수 | Oracle 구현 | MySQL용 Cloud SQL 상응 | MySQL용 Cloud SQL 함수 |
---|---|---|---|
EXISTS/
NOT EXISTS
|
예 |
EXISTS/
NOT EXISTS
|
SELECT * FROM DEPARTMENTS D
WHERE EXISTS (SELECT 1
FROM EMPLOYEES E
WHERE
E.DEPARTMENT_ID =
D.DEPARTMENT_ID);
|
IN/NOT IN |
예 | IN/NOT IN |
SELECT * FROM DEPARTMENTS D
WHERE DEPARTMENT_ID IN
(SELECT DEPARTMENT_ID
FROM EMPLOYEES E);
-- OR
SELECT * FROM EMPLOYEES
WHERE (EMPLOYEE_ID, DEPARTMENT_ID)
IN((100, 90));
|
LIKE/NOT LIKE |
예 | LIKE/NOT LIKE |
SELECT * FROM EMPLOYEES
WHERE FIRST_NAME LIKE '_e_n%';
|
BETWEEN/
NOT BETWEEN
|
예 |
BETWEEN/
NOT BETWEEN
|
SELECT * FROM EMPLOYEES
WHERE EXTRACT(YEAR FROM HIRE_DATE)
NOT BETWEEN 2001 and 2004;
|
AND/OR |
예 | AND/OR |
SELECT * FROM EMPLOYEES
WHERE DEPARTMENT_ID IN(100, 101)
AND (SALARY >= 1000 OR HIRE_DATE <= '2006-02-05');
|
SubQuery |
예 | SubQuery |
MySQL용 Cloud SQL은 SELECT 절과 JOIN 절에서 그리고 WHERE/AND 절에서의 필터링에 대해 서브 쿼리를 지원합니다.
-- SELECT Subquery
SELECT D.DEPARTMENT_NAME,
(SELECT AVG(SALARY) AS AVG_SAL
FROM EMPLOYEES E
WHERE E.DEPARTMENT_ID =
D.DEPARTMENT_ID) AVG_SAL
FROM DEPARTMENTS D;
-- JOIN Subquery
SELECT FIRST_NAME, LAST_NAME, SALARY
FROM EMPLOYEES E JOIN
(SELECT *
FROM DEPARTMENTS
WHERE LOCATION_ID = 2700) D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
-- Filtering Subquery
SELECT FIRST_NAME,
LAST_NAME,
SALARY
FROM EMPLOYEES
WHERE SALARY < (SELECT AVG(SALARY)
FROM EMPLOYEES);
|
연산자 | 예 | 연산자 | MySQL용 Cloud SQL은 모든 기본 연산자를 지원합니다.> | >= | < | <= | = | <> | !=
|
MySQL용 Cloud SQL 쿼리 권장사항
MySQL용 Cloud SQL과 Oracle 사이의 성능을 비슷한 수준으로 유지하기 위해서는 쿼리를 최적화해야 할 수 있습니다. 이러한 최적화에는 색인 구조 변경과 데이터베이스 스키마 조정이 포함됩니다. 이 섹션에서는 MySQL용 Cloud SQL에서 비슷한 쿼리 성능을 얻는 데 도움이 되는 몇 가지 가이드라인을 제공합니다.
클러스터링된 인덱스 만들기
InnoDB 스토리지 엔진을 사용할 때 권장사항은 기본 키로 테이블을 정의하는 것입니다. 이 키가 해당 테이블에 클러스터링된 색인을 만들기 때문입니다. 이렇게 하면 쿼리 성능이 향상될 뿐만 아니라 추가적인 보조 색인도 만들 수 있습니다. 물론 색인이 너무 많아지는 것은 피하는 것이 좋습니다. 중복 색인이 있어도 성능은 향상되지 않고 DML 실행이 느려질 수 있습니다. 이 권장사항은 중복 색인을 정기적으로 모니터링해야 하는 두 번째 권장사항으로 이어집니다. 중복 항목이 있으면 데이터베이스에서 이를 삭제해야 합니다.
기본 키를 만들 수 있도록 다음 쿼리를 사용해서 기본 키가 없는 테이블을 식별합니다.
mysql> SELECT t.table_schema, t.table_name
FROM information_schema.tables t LEFT JOIN
information_schema.statistics s
ON t.table_schema=s.table_schema AND t.table_name=s.table_name
AND s.non_unique=0
WHERE s.table_name IS NULL
AND t.table_schema NOT IN('sys', 'information_schema', 'mysql',
'performance_schema')
AND t.`TABLE_TYPE` <> 'VIEW';
색인을 만들 수 있도록 다음 쿼리를 사용해서 색인이 없는 테이블을 찾습니다.
mysql> SELECT t.table_schema, t.table_name FROM INFORMATION_SCHEMA.tables t
WHERE table_name NOT IN
(SELECT table_name FROM (
SELECT table_name, index_name
FROM information_schema.statistics
GROUP BY table_name, index_name) tab_ind_cols
GROUP BY table_name)
AND table_schema NOT IN('sys', 'information_schema', 'mysql', 'performance_schema')
AND TABLE_TYPE <> 'VIEW';
중복 항목을 삭제할 수 있도록 다음 쿼리를 사용하여 중복 색인을 확인합니다.
mysql> SELECT * FROM sys.schema_redundant_indexes;
쿼리 매개변수 조정
쿼리 성능을 조정하려면 세션 매개변수를 조정해야 할 수 있습니다. MySQL용 Cloud SQL에는 다음 플래그를 포함하여 이 목적으로 필터링할 수 있는 플래그 집합이 있습니다.
- InnoDB 관련 매개변수
SORT
매개변수JOIN
매개변수- 캐시 처리 매개변수
쿼리 모니터링
실행 속도가 느린 쿼리로 인해 시스템이 응답하지 않거나 다른 병목 현상이 발생할 수 있으므로 쿼리를 정기적으로 모니터링하는 것이 중요합니다.
실행이 느린 SQL 문은 여러 방법으로 진단할 수 있습니다.
- MySQL용 Cloud SQL 대시보드를 사용하여 실행이 느린 쿼리에 대한 실시간 및 이전 정보를 확인합니다.
- Cloud Monitoring을 사용하여 MySQL용 Cloud SQL에서 느린 쿼리 로그를 모니터링합니다.
MySQL용 Cloud SQL
statement_analysis
뷰를 사용하여 SQL 문에 대한 런타임 통계를 확인합니다.mysql> SELECT * FROM sys.statement_analysis;
MySQL용 Cloud SQL 쿼리 분석
MySQL용 Cloud SQL의 쿼리 옵티마이저는 SELECT
, INSERT
, UPDATE
, DELETE
문의 실행 계획을 생성합니다. 이러한 계획은 실행이 느린 쿼리를 조정할 때 유용합니다. 다음 몇 가지 사항에 유의해야 합니다.
- 실행 계획은 마이그레이션이 필요한 데이터베이스 객체가 아닙니다. 오히려 동일 데이터베이스에서 동일 문을 실행하여 Oracle과 MySQL용 Cloud SQL 사이의 성능 차이를 분석하기 위한 도구입니다.
- MySQL용 Cloud SQL은 Oracle과 동일한 실행 계획 구문, 기능, 출력을 지원하지 않습니다.
다음은 Oracle 실행 계획과 MySQL용 Cloud SQL 실행 계획 사이의 차이를 보여주는 예시 계획입니다.
SQL> EXPLAIN PLAN FOR
SELECT * FROM EMPLOYEES WHERE EMPLOYEE_ID = 105;
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY (FORMAT=>'ALL +OUTLINE'));
Plan hash value: 1833546154
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 69 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 69 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
mysql> EXPLAIN SELECT * FROM EMPLOYEES WHERE EMPLOYEE_ID = 105;
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | EMPLOYEES | NULL | const | PRIMARY | PRIMARY | 3 | const | 1 | 100.00 | NULL |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
저장 프로시져와 트리거 최적화
Oracle과 달리 MySQL용 Cloud SQL 저장 프로시져와 함수는 각각 실행될 때 구문 분석됩니다. 저장 프로시져와 함수 성능을 벤치마크하기 위한 유용한 도구는 MySQL BENCHMARK()
유틸리티입니다.
이 도구는 두 매개변수인 반복 횟수와 표현식을 사용해서 제공된 표현식의 런타임을 예상합니다(예: 저장 프로시져, 함수, SELECT
문). 출력은 모든 반복에 대한 대략적인 런타임 합계를 나타냅니다.
다음은 BENCHMARK()
유틸리티를 설명하는 예시입니다.
-- SELECT Expression Example
mysql> select benchmark(10000000, 'select sysdate()');
+-----------------------------------------+
| benchmark(10000000, 'select sysdate()') |
+-----------------------------------------+
| 0 |
+-----------------------------------------+
1 row in set (0.12 sec)
-- Result: Run time of 0.12 sec for 1,0000,000 iterations
-- FUNCTION Example
mysql> select benchmark(1000000, func1());
+-----------------------------+
| benchmark(1000000, func1()) |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (2.54 sec)
-- Result: Run time of 2.54 sec for 1,000,000 iterations
변환 중 성능 저하가 눈에 띄면 MySQL EXPLAIN
명령어를 사용하여 성능 저하에 영향을 줄 수 있는 가능한 요소들을 식별합니다. 느린 성능에 대한 일반적인 해결 방법 중 하나는 MySQL 옵티마이저를 사용하도록 테이블 색인 구조를 변경하는 것입니다. 또 다른 일반적인 방법은 불필요한 데이터 검색을 줄이거나 프로시져 MySQL 코드 내에서 임시 테이블을 사용하여 변환된 PL/SQL 코드를 최적화하는 것입니다.
다음 단계
- MySQL 사용자 계정에 대해 알아봅니다.
- Google Cloud에 대한 참조 아키텍처, 다이어그램, 권장사항 살펴보기 Cloud 아키텍처 센터 살펴보기