このドキュメントでは、Oracle® と Cloud SQL for MySQL の基本的なクエリの違いと、Oracle の機能がどのように Cloud SQL for MySQL の機能に対応するかについて説明します。また、Cloud SQL for MySQL のパフォーマンスに関する考慮事項と、Google Cloud でクエリのパフォーマンスを分析して最適化する方法についても説明します。このドキュメントでは、Cloud SQL for MySQL のストアド プロシージャとトリガーを最適化する手法に触れますが、PL/SQL コードを MySQL のストアド プロシージャと関数に変換する方法については説明しません。
クエリを Oracle Database から Cloud SQL for MySQL に変換する場合は、SQL 言語上の違いについていくつか考慮する必要があります。また、2 つのデータベース プラットフォーム間で異なるか、互換性のない組み込み関数もいくつかあります。
基本的なクエリの違い
Oracle と Cloud SQL for MySQL はどちらも ANSI SQL をサポートしていますが、データのクエリを行う際には、主にシステム関数の使用に関していくつかの基本的な違いがあります。
次の表に、Oracle と Cloud SQL for MySQL の SELECT
構文と FROM
構文の違いを示しています。
Oracle の機能名 | Oracle の実装 | Cloud SQL for MySQL のサポート | Cloud SQL for MySQL の同等機能 |
---|---|---|---|
データ取得のための 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
ステートメントであり、サブクエリとして使用されます。インライン ビューを利用して複合計算を削除したり、結合オペレーションを排除したりすると、複雑なクエリをシンプルにできます。また、複数の個別クエリを 1 つの簡素化されたクエリに要約することもできます。
次の例では、インライン ビューでの Oracle 11g/12c から Cloud SQL for MySQL への変換例を示しています。
Oracle 11g/12c のインライン ビュー:
SELECT FIRST_NAME,
DEPARTMENT_ID,
SALARY,
DATE_COL
FROM EMPLOYEES,
(SELECT SYSDATE AS DATE_COL FROM DUAL);
Cloud SQL for MySQL 5.7 のエイリアスを使用した作業ビュー:
SELECT FIRST_NAME,
DEPARTMENT_ID,
SALARY,
DATE_COL
FROM EMPLOYEES, (SELECT SYSDATE() AS DATE_COL FROM DUAL) AS A1;
結合
Oracle の結合タイプは、FULL JOIN
を除いて Cloud SQL for MySQL でサポートされています。Cloud SQL for MySQL の結合では、ON
句、JOIN
ステートメントの SUBQUERY
句の代わりに USING
句、WHERE
句などの代替構文が使用できます。
次の表に、JOIN
変換の例を示します。
Oracle JOIN タイプ |
Cloud SQL for MySQL のサポート | Cloud SQL for MySQL の 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 |
× | UNION と LEFT の使用および RIGHT JOINS:
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;
|
Cloud SQL for MySQL では UNION
関数と UNION ALL
関数の両方をサポートしていますが、Oracle の INTERSECT
関数と MINUS
関数はサポートしていません。
UNION
は、重複するレコードを除外してから、2 つのSELECT
ステートメントの結果セットをアタッチします。UNION ALL
は、重複するレコードを除外せずに、2 つのSELECT
ステートメントの結果セットをアタッチします。INTERSECT
は、両方のクエリの結果セットにレコードが存在する場合にのみ、2 つのSELECT
ステートメントの共通する部分を返します。MINUS
は、2 つ以上のSELECT
ステートメントを比較し、最初のクエリで 2 番目のクエリから返されない個別の行のみを返します。
次の表に、Oracle から Cloud SQL for MySQL への変換の例をいくつか示します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL のサポート | Cloud SQL for MySQL の同等機能 |
---|---|---|---|
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
|
スカラー関数とグループ関数
Cloud SQL for MySQL には、さまざまなスカラー(単一行)関数と集計関数が用意されています。一部の Cloud SQL for MySQL 関数は、対応する Oracle 関数に非常によく似ています(名前と機能が似ている関数や、名前は異なっていても機能が似ている関数などがあります)。Cloud SQL for MySQL の関数によっては、Oracle での対応する関数名と同じ名前が使用されていても、機能がそれぞれ異なる場合もあります。
次の表に、Oracle と Cloud SQL for MySQL の文字関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
CONCAT |
最初の文字列を 2 番目の文字列と連結して返します。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 |
expression1 の左側または右側に、expression2 で指定した文字を連続的に埋め込んで n 桁にして返します。LPAD('A',3,'*') = **A |
○ | LPAD または RPAD |
LPAD('A',3,'*') = **A |
SUBSTR |
位置 x から始まり(この例では 3)、長さが 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 関数では、2 番目のパラメータで文字列から削除する先頭または末尾の文字を指定します。Cloud SQL for MySQL 関数では、指定された文字列から先頭と末尾の空白のみを削除します。
LTRIM(' MySQL')
= MySQL
|
ASCII |
1 文字を受け取り、その ASCII コードを数値で返します。ASCII('A') = 65
|
○ | ASCII |
ASCII('A') = 65 |
CHR |
ASCII コード値(0~225 の数値)を文字に戻します。CHR(65) = A
|
関数名が異なります | CHAR |
Cloud SQL for MySQL は同じ機能に 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 |
ソース文字列でのパターン出現回数を返します。 | × | なし | Cloud SQL for MySQL で使用できる同等の関数はありません。このロジックはアプリケーション層に移動してください。 |
REGEXP_INSTR |
正規表現パターンに一致する文字列の位置(インデックス)を検索します。 | × | なし | MySQL バージョン 8 以降でサポートされます。古いバージョンの場合は、このロジックはアプリケーション層に移動してください。 |
REVERSE |
指定された文字列の逆の文字列を返します。
REVERSE('MySQL')
= LQSyM
|
○ | REVERSE |
REVERSE('MySQL')
= LQSyM
|
次の表に、Oracle と Cloud SQL for MySQL の数値関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
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 (number) |
n1 を小数点以下 n2 桁に切り捨てて返します。2 番目のパラメータは省略可能です。
TRUNC(99.999) = 99
TRUNC(99.999, 0) = 99
|
関数名が異なります | TRUNCATE (number) |
Cloud SQL for MySQL 関数には別の名前があり、2 番目のパラメータは必須です。TRUNCATE(99.999, 0) = 99 |
次の表に、Oracle と Cloud SQL for MySQL の datetime
関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
SYSDATE |
データベース サーバーが存在するオペレーティング システムに設定されている現在の日付と時刻を返します。
SELECT SYSDATE
FROM DUAL;
= 31-JUL-2019
|
○ | SYSDATE() |
Cloud SQL for MySQL の
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
|
Cloud SQL for MySQL 関数では、デフォルトで異なる 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
|
Cloud SQL for MySQL 関数では、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
|
Cloud SQL for MySQL 関数では、異なる 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
|
Cloud SQL for MySQL 関数では、異なる datetime 形式を返します。出力の形式を変更する場合は、DATE_FORMAT() 関数を使用します。
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 2019-01-31 06:55:07
|
ADD_MONTHS |
日付と、月を表す整数を返します。
ADD_MONTHS(SYSDATE, 1)
= 31-JAN-19
|
関数名が異なります | ADDDATE |
Cloud SQL for MySQL 関数では、異なる datetime 形式を返します。出力の形式を変更する場合は、DATE_FORMAT() 関数を使用します。
ADDDATE(SYSDATE(), 1)
= 2019-08-01 06:42:49.0
|
EXTRACT (date part) |
期間の式に基づいて datetime フィールドの値を返します。
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
|
○ | EXTRACT (date part) |
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
|
LAST_DAY |
指定された日付の月の最終日を返します。
LAST_DAY('01-JAN-2019')
= 31-JAN-19
|
部分的 | LAST_DAY |
Cloud SQL for MySQL 関数では、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
|
Cloud SQL for MySQL の PERIOD_DIFF 関数は、2 つの日付期間(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 |
Cloud SQL for MySQL の DATE_FORMAT 関数では、フォーマット文字列に従って日付値をフォーマットします。
DATE_FORMAT(
SYSDATE(),'%d-%m-%Y %H:%i:%s')
01-01-2019 10:01:01
|
次の表に、Oracle と Cloud SQL for MySQL のエンコード関数とデコード関数で、名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
DECODE |
IF-THEN-ELSE ステートメントの機能を使用して、各検索値を 1 つずつ式と比較します。 |
× | CASE |
Cloud SQL for MySQL の CASE ステートメントを使用して同様の機能を実現します |
DUMP |
データ型のコード、長さ(バイト数)、式の内部表現を含む VARCHAR2 値を返します。 |
× | なし | 非対応 |
ORA_HASH |
指定した式のハッシュ値を計算します。 | × | MD5 or SHA |
128 ビット チェックサムには MD5 関数を使用し、160 ビット チェックサムには SHA 関数を使用します。 |
次の表に、Oracle と Cloud SQL for MySQL の変換関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
CAST |
1 つの組み込みデータ型または集合型の値を別の組み込みデータ型または集合型の値に変換します。
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 |
Cloud SQL for MySQL CONVERT 関数では、構文とパラメータを調整する必要があります。
CONVERT(
'Ä Ê Í A B C ' USING utf8)
= Ä Ê Í A B C
|
TO_CHAR (string/numeric) |
この関数は数値または日付を文字列に変換します。
TO_CHAR(22.73,'$99.9')
= $22.7
|
× | FORMAT |
Cloud SQL for MySQL の 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 |
Cloud SQL for MySQL の STR_TO_DATE 関数は、文字列を受け取り、datetime 形式に基づいて日付を返します。
STR_TO_DATE(
'2019/01/01', '%Y/%m/%d')
= 2019-01-01
|
TO_NUMBER |
式を NUMBER データ型の値に変換します。
TO_NUMBER('01234')
= 1234
|
関数名が異なります | CAST |
Cloud SQL for MySQL の CAST 関数を使用して、Oracle の TO_NUMBER 関数と同じ結果を返します。
CAST('01234' as SIGNED)
= 1234
|
次の表に、Oracle と Cloud SQL for MySQL の条件付き SELECT
関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
CASE |
CASE ステートメントは、一連の条件に基づいて対応するステートメントを選択して実行します。構文は次のとおりです。
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
|
○ | CASE |
Cloud SQL for MySQL では、CASE 関数だけでなく、SELECT ステートメント内で IF/ELSE を使用して条件付きの処理を行うこともできます。
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
|
次の表に、Oracle と Cloud SQL for MySQL の null 関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
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 と Cloud SQL for MySQL の環境関数と ID 関数で、名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
SYS_GUID |
16 バイトからなる、グローバルに一意の ID(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 |
Cloud SQL for MySQL の 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
|
Cloud SQL for MySQL の 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 と Cloud SQL for MySQL の集計(グループ)関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
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
|
Cloud SQL for MySQL の GROUP_CONCAT 関数を使用して、同等の結果を返します。
SELECT GROUP_CONCAT(
DEPARTMENT_NAME ORDER BY DEPARTMENT_NAME SEPARATOR ', ') DEPT
FROM DEPARTMENTS;
-- Single line results
= Accounting, Administration, Benefits, Construction
|
次の表に、Oracle と Cloud SQL for MySQL の FETCH
関数で名前と機能が同じ関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 | Cloud SQL for MySQL の実装 |
---|---|---|---|---|
FETCH |
複数行クエリの結果セットから指定した数の行を取得します。
SELECT * FROM
EMPLOYEES
FETCH FIRST 10 ROWS ONLY;
|
○ | LIMIT |
MySQL の LIMIT 句を使用して、クエリから行を取得します。
SELECT * FROM
EMPLOYEES
LIMIT 10;
|
基本的なフィルタリング、演算子、サブクエリ
基本的なフィルタリング、演算子関数、サブクエリは、わずかな作業で比較的簡単に変換できます。Oracle と Cloud SQL for MySQL ではデフォルトの日付形式が異なるため、ほとんどは日付形式の変換に関連する作業です。
- Oracle の
SYSDATE
関数は、01-AUG-19
というデフォルトの形式で返します。 - Cloud SQL for MySQL の
SYSDATE()
関数は、2019-08-01 12:04:05
というデフォルトの形式で返します。
日付と時刻の形式を設定するには、MySQL の DATE_FORMAT
関数または STR_TO_DATE
関数を使用します。
次の表に、Oracle と Cloud SQL for MySQL の基本的なフィルタリング、演算子、サブクエリの関数で名前と機能が同じ関数と、変換が推奨される関数を記載します。
Oracle の関数 | Oracle の実装 | Cloud SQL for MySQL の同等機能 | Cloud SQL for MySQL の関数 |
---|---|---|---|
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 |
Cloud SQL for MySQL では、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);
|
演算子 | ○ | 演算子 | Cloud SQL for MySQL はすべての基本的な演算子をサポートしています。> | >= | < | <= | = | <> | !=
|
Cloud SQL for MySQL クエリのベスト プラクティス
Cloud SQL for MySQL と Oracle の間で同程度のパフォーマンスを維持するには、クエリを最適化する必要があります。これらの最適化には、インデックス構造の変更とデータベース スキーマの調整が含まれます。このセクションでは、Cloud SQL for MySQL で同等のクエリ パフォーマンスを実現するためのガイドラインをいくつか紹介します。
クラスタ化インデックスの作成
InnoDB ストレージ エンジンを使用する場合は、主キーを持つテーブルを定義することをおすすめします。このキーにより、そのテーブルのクラスタ化インデックスが作成されるためです。この方法を使用すると、クエリのパフォーマンスが向上するだけでなく、追加のセカンダリ インデックスを作成することもできます。ただし、インデックスを作成しすぎないようにしてください。冗長なインデックスがあるとパフォーマンスは向上せず、DML の実行速度が低下する可能性があります。このベスト プラクティスは 2 番目のベスト プラクティスにつながります。冗長なインデックスを定期的にモニタリングし、冗長なインデックスがある場合はデータベースから削除します。
次のクエリを使用すると、主キーのないテーブルを特定して、そのテーブルの主キーを作成できます。
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;
クエリ パラメータの調整
クエリのパフォーマンスを調整するには、セッション パラメータを調整することが必要な場合があります。Cloud SQL for MySQL には、この目的のために変更できる一連のフラグがあります。次のようなフラグが含まれます。
- InnoDB 関連のパラメータ
SORT
パラメータJOIN
パラメータ- キャッシュ処理パラメータ
クエリのモニタリング
実行速度が遅いクエリは、システムが応答を停止する原因となる、または他のボトルネックの要因となる可能性があります。そのため、定期的にクエリをモニタリングすることが重要です。
実行速度が遅い SQL ステートメントを診断するには、いくつかの方法があります。
- Cloud SQL for MySQL ダッシュボードを使用すると、実行速度が遅いクエリに関するリアルタイムの、および過去に遡った分析情報を取得できます。
- Cloud Monitoring を使用して、Cloud SQL for MySQL のスロークエリ ログをモニタリングします。
Cloud SQL for MySQL の
statement_analysis
ビューを使用して、SQL ステートメントに関するランタイム統計情報を表示します。mysql> SELECT * FROM sys.statement_analysis;
Cloud SQL for MySQL クエリの分析
Cloud SQL for MySQL のクエリ オプティマイザーは、SELECT
、INSERT
、UPDATE
、DELETE
の各ステートメントの実行プランを生成します。これらのプランは、実行速度の遅いクエリを調整する場合に役立ちます。使用する場合は以下のことについてご理解ください。
- 実行プランは移行の必要があるデータベース オブジェクトではありません。これは、同じデータセットに対して同じステートメントを実行する場合に、Oracle と Cloud SQL for MySQL の間のパフォーマンスの違いを分析するためのツールです。
- Cloud SQL for MySQL でサポートしている実行プランの構文、機能、出力は、Oracle とは異なります。
次に、Oracle の実行プランと Cloud SQL for MySQL の実行プランの違いを説明するためのプランの例を示します。
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 とは異なり、Cloud SQL for MySQL のストアド プロシージャと関数は実行のたびに解析されます。MySQL BENCHMARK()
ユーティリティは、ストアド プロシージャと関数のパフォーマンスのベンチマーキングに役立つツールです。このツールは、反復回数と式の 2 つのパラメータを取り、指定された式(ストアド プロシージャ、関数、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
コマンドを使用して、考えられるパフォーマンス低下の原因を特定します。パフォーマンス低下の一般的な解決策の 1 つは、MySQL オプティマイザーに対応するためにテーブルのインデックス構造を変更することです。もう 1 つの一般的な方法は、不要なデータ検索を減らしたり、手続き型 MySQL コード内の一時テーブルを使用したりすることです。
次のステップ
- MySQL のユーザー アカウントの詳細を確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターをご覧ください。