Mengonversi dan mengoptimalkan kueri dari Database Oracle ke Cloud SQL untuk MySQL

Dokumen ini membahas perbedaan kueri dasar antara Oracle® dan Cloud SQL untuk MySQL, serta pemetaan fitur di Oracle ke fitur di Cloud SQL untuk MySQL. Dokumen ini juga menguraikan pertimbangan performa untuk Cloud SQL untuk MySQL dan cara menganalisis serta mengoptimalkan performa kueri diGoogle Cloud. Meskipun membahas teknik mengoptimalkan prosedur dan pemicu tersimpan untuk Cloud SQL untuk MySQL, dokumen ini tidak membahas cara menerjemahkan kode PL/SQL menjadi prosedur dan fungsi tersimpan di MySQL.

Saat mengonversi kueri dari Oracle Database ke Cloud SQL untuk MySQL, ada perbedaan dialek SQL tertentu yang perlu dipertimbangkan. Ada juga beberapa fungsi bawaan yang berbeda atau tidak kompatibel antara kedua platform database tersebut.

Perbedaan kueri dasar

Meskipun Oracle dan Cloud SQL untuk MySQL sama-sama mendukung ANSI SQL, ada beberapa perbedaan mendasar saat mengkueri data, terutama seputar penggunaan fungsi sistem.

Tabel berikut menunjukkan perbedaan sintaksis SELECT dan FROM untuk Oracle dan Cloud SQL untuk MySQL.

Nama fitur di Oracle Implementasi di Oracle Dukungan di Cloud SQL untuk MySQL Setara dengan Cloud SQL untuk MySQL
Sintaksis dasar SQL untuk pengambilan data SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
Ya SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT untuk cetak output SELECT 1 FROM DUAL Ya SELECT 1
atau
SELECT 1 FROM DUAL
Alias kolom SELECT COL1 AS C1 Ya SELECT COL1 AS C1
atau
SELECT COL1 C1
Kepekaan huruf besar/kecil nama tabel Tidak ada kepekaan huruf besar/kecil (misalnya, nama tabel dapat berupa orders dan ORDERS) Tidak Peka huruf besar/kecil sesuai dengan nama tabel yang ditentukan (misalnya, nama tabel hanya boleh orders atau ORDERS)

Tabel virtual inline

Tabel virtual inline (disebut juga tabel turunan) adalah pernyataan SELECT, yang terletak di klausa FROM, dan digunakan sebagai subkueri. Tabel virtual inline dapat membantu menyederhanakan kueri yang kompleks dengan menghapus penghitungan gabungan atau menghilangkan operasi join, sekaligus menggabungkan beberapa kueri terpisah menjadi satu kueri yang disederhanakan.

Contoh berikut menguraikan contoh konversi dari Oracle 11g/12c ke Cloud SQL untuk MySQL untuk tabel virtual inline.

Tabel virtual inline di Oracle 11g/12c:

 SELECT FIRST_NAME,
            DEPARTMENT_ID,
            SALARY,
            DATE_COL
     FROM EMPLOYEES,
          (SELECT SYSDATE AS DATE_COL FROM DUAL);

Tampilan kerja di Cloud SQL untuk MySQL 5.7 dengan alias:

SELECT FIRST_NAME,
              DEPARTMENT_ID,
              SALARY,
              DATE_COL
       FROM EMPLOYEES, (SELECT SYSDATE() AS DATE_COL FROM DUAL) AS A1;

Join

Jenis-jenis join Oracle didukung oleh Cloud SQL untuk MySQL, kecuali FULL JOIN. Join di Cloud SQL untuk MySQL mendukung penggunaan sintaksis alternatif, seperti klausa USING, klausa WHERE alih-alih klausa ON, dan SUBQUERY dalam JOIN.

Tabel berikut menunjukkan contoh konversi JOIN.

Jenis JOIN di Oracle Dukungan di Cloud SQL untuk MySQL Sintaksis JOIN di Cloud SQL untuk MySQL
INNER JOIN Ya SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E JOIN DEPARTMENTS D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
CROSS JOIN Ya SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E CROSS JOIN DEPARTMENTS D
FULL JOIN Tidak Sebaiknya gunakan UNION dengan LEFT dan 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 ] Ya SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
RIGHT JOIN [ OUTER ] Ya SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E RIGHT JOIN DEPARTMENTS D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
SUBQUERY Ya SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E JOIN (SELECT * FROM DEPARTMENTS)D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

Meskipun mendukung fungsi UNION dan UNION ALL, Cloud SQL untuk MySQL tidak mendukung fungsi INTERSECT dan MINUS Oracle:

  • UNION melampirkan kumpulan hasil dari dua pernyataan SELECT setelah menghapus data duplikat.
  • UNION ALL melampirkan kumpulan hasil dari dua pernyataan SELECT tanpa menghapus data duplikat.
  • INTERSECT menampilkan irisan dari dua pernyataan SELECT, hanya jika data ada dalam kumpulan hasil dari kedua kueri.
  • MINUS membandingkan dua pernyataan SELECT atau lebih, dengan hanya menampilkan baris berbeda dari kueri pertama yang tidak ditampilkan oleh kueri kedua.

Tabel berikut menunjukkan beberapa contoh konversi Oracle ke Cloud SQL untuk MySQL.

Fungsi di Oracle Implementasi di Oracle Dukungan di Cloud SQL untuk MySQL Setara dengan Cloud SQL untuk MySQL
UNION SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
Ya SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
UNION ALL SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
Ya SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
INTERSECT SELECT COL1 FROM TBL1
INTERSECT
SELECT COL1 FROM TBL2
Tidak SELECT COL1 FROM TBL1
WHERE COL1 IN
(SELECT COL1 FROM TBL2)
MINUS SELECT COL1 FROM TBL1
MINUS
SELECT COL1 FROM TBL2
Tidak SELECT A.COL1 FROM TBL1 A LEFT JOIN TBL2 B ON USING(COL1) WHERE B.COL1 IS NULL

Fungsi skalar dan grup

Cloud SQL untuk MySQL menyediakan daftar lengkap fungsi skalar (baris tunggal) dan agregasi. Beberapa fungsi Cloud SQL untuk MySQL mirip dengan fungsi padanannya di Oracle (berdasarkan nama dan fungsionalitas, atau dengan nama berbeda tetapi fungsionalitas sama). Meskipun beberapa fungsi Cloud SQL untuk MySQL dapat memiliki nama yang sama dengan fungsi padanannya di Oracle, fungsionalitasnya dapat berbeda.

Tabel berikut menjelaskan elemen fungsi karakter di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
CONCAT Menampilkan string pertama yang disambungkan dengan string kedua:
CONCAT('A', 1) = A1
Ya CONCAT CONCAT('A', 1) = A1
CONCAT USING PIPE FNAME |' '| LNAME Tidak CONCAT CONCAT(FNAME, ' ', LNAME)
LOWER atau UPPER Menampilkan string, dengan semua huruf ditulis dalam huruf kecil atau huruf besar:
LOWER('SQL') = sql
Ya LOWER atau UPPER LOWER('SQL') = sql
LPAD/RPAD Menampilkan expression1, dengan padding kiri atau kanan hingga sepanjang n karakter dengan urutan karakter di expression2:
LPAD('A',3,'*') = **A
Ya LPAD atau RPAD LPAD('A',3,'*') = **A
SUBSTR Menampilkan sebagian string, mulai dari posisi x (dalam kasus ini 3), dengan panjang y. Posisi pertama dalam string adalah 1.
SUBSTR('MySQL', 3, 3) = SQL
Ya SUBSTR SUBSTR('MySQL', 3, 3) = SQL
INSTR Menampilkan posisi (indeks) sebuah string dari string tertentu:
INSTR('MySQL', 'y') = 2
Ya INSTR INSTR('MySQL', 'y') = 2
REPLACE Menampilkan string dengan setiap kemunculan string penelusuran diganti dengan string pengganti:
REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
Ya REPLACE REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
TRIM Memangkas karakter di awal atau di akhir string (atau keduanya):
TRIM(both '-' FROM '-MySQL-') = MySQL TRIM(' MySQL ') = MySQL
Ya TRIM TRIM(both '-' FROM '-MySQL-') = MySQL TRIM(' MySQL ') = MySQL
LTRIM/RTRIM Menghapus semua karakter yang muncul dalam penelusuran dari ujung kiri atau kanan string:
LTRIM(' MySQL', ' ') = MySQL
Sebagian LTRIM or RTRIM Fungsi LTRIM dan RTRIM Oracle menggunakan parameter kedua yang menentukan karakter di awal atau di akhir yang harus dihapus dari string. Di Cloud SQL untuk MySQL, fungsi ini hanya menghapus spasi kosong di awal dan di akhir string yang ditentukan:
LTRIM(' MySQL') = MySQL
ASCII Mengambil satu karakter dan menampilkan kode ASCII numeriknya:
ASCII('A') = 65
Ya ASCII ASCII('A') = 65
CHR Menampilkan nilai kode ASCII, yang merupakan nilai numerik antara 0 dan 225, hingga sebuah karakter:
CHR(65) = A
Memerlukan nama fungsi yang berbeda CHAR Cloud SQL untuk MySQL menggunakan fungsi CHAR untuk fungsionalitas yang sama, sehingga Anda perlu mengubah nama fungsi:
CHAR(65) = A
LENGTH Menampilkan panjang string tertentu:
LENGTH('MySQL') = 5
Ya LENGTH LENGTH('MySQL') = 5
REGEXP_REPLACE Mencari pola ekspresi reguler dalam string:
REGEXP_REPLACE('John', '[hn].', 'e') = Joe
Tidak T/A Didukung mulai MySQL versi 8. Sebagai solusinya, gunakan fungsi REPLACE jika memungkinkan atau pindahkan logika ke lapisan aplikasi.
REGEXP_SUBSTR Memperluas fungsionalitas fungsi SUBSTR dengan mencari pola ekspresi reguler dalam string:
REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?') = https://console.cloud.google.com/
Tidak T/A Didukung mulai MySQL versi 8. Sebagai solusinya, gunakan fungsi SUBSTR jika memungkinkan atau pindahkan logika ini ke lapisan aplikasi
REGEXP_COUNT Menampilkan frekuensi kemunculan pola di sebuah string sumber Tidak T/A Tidak ada fungsi setara yang tersedia untuk Cloud SQL untuk MySQL. Pindahkan logika ini ke lapisan aplikasi.
REGEXP_INSTR Mencari pola ekspresi reguler dalam posisi string (indeks) Tidak T/A Didukung mulai MySQL versi 8. Jika menggunakan versi lebih lama, pindahkan logika ini ke lapisan aplikasi.
REVERSE Menampilkan string terbalik untuk string tertentu:
REVERSE('MySQL') = LQSyM
Ya REVERSE REVERSE('MySQL') = LQSyM

Tabel berikut menjelaskan elemen fungsi numerik di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
ABS Menampilkan nilai absolut angka tertentu:
ABS(-4.6) = 4.6
Ya ABS ABS(-4.6) = 4.6
CEIL Menampilkan bilangan bulat terkecil yang lebih besar daripada atau sama dengan bilangan yang ditentukan:
CEIL(21.4) = 22
Ya CEIL CEIL(21.4) = 22
FLOOR Menampilkan bilangan bulat terbesar yang sama dengan atau lebih kecil daripada bilangan yang ditentukan:
FLOOR(-23.7) = -24
Ya FLOOR FLOOR(-23.7) = -24
MOD Menampilkan sisa m dibagi n:
MOD(10, 3) = 1
Ya MOD MOD(10, 3) = 1
ROUND Menampilkan n yang dibulatkan ke tempat bilangan bulat di kanan tanda desimal:
ROUND(1.39, 1) = 1.4
Ya ROUND ROUND(1.39, 1) = 1.4
TRUNC(angka) Menampilkan n1 yang dipotong ke n2 angka di belakang koma. Parameter kedua bersifat opsional.
TRUNC(99.999) = 99 TRUNC(99.999, 0) = 99
Memerlukan nama fungsi yang berbeda TRUNCATE(angka) Fungsi di Cloud SQL untuk MySQL memiliki nama berbeda dan parameter kedua bersifat wajib.
TRUNCATE(99.999, 0) = 99

Tabel berikut menjelaskan elemen fungsi datetime di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
SYSDATE Menampilkan tanggal dan waktu saat ini yang ditetapkan untuk sistem operasi tempat server database berada:
SELECT SYSDATE FROM DUAL; = 31-JUL-2019
Ya SYSDATE()

Fungsi SYSDATE() di Cloud SQL untuk MySQL harus menyertakan tanda kurung dan secara default menampilkan format datetime yang berbeda dari fungsi SYSDATE di Oracle:

SELECT SYSDATE() FROM DUAL; = 2019-01-31 10:01:01.0

Anda dapat mengubah format datetime di tingkat sesi

SYSTIMESTAMP Menampilkan tanggal sistem, termasuk detik pecahan dan zona waktu:
SELECT SYSTIMESTAMP FROM DUAL = 01-JAN-19 07.37.11.622187000 AM +00:00
Memerlukan nama fungsi yang berbeda CURRENT_ TIMESTAMP Fungsi di Cloud SQL untuk MySQL menampilkan format datetime yang berbeda secara default. Untuk memformat ulang output, gunakan fungsi DATE_FORMAT().
SELECT CURRENT_TIMESTAMP FROM DUAL; = 2019-01-31 06:55:07
LOCAL_ TIMESTAMP Menampilkan tanggal dan waktu saat ini sebagai jenis TIMESTAMP:
SELECT LOCALTIMESTAMP FROM DUAL = 01-JAN-19 10.01.10.123456 PM
Menampilkan format datetime yang berbeda LOCAL_ TIMESTAMP Fungsi di Cloud SQL untuk MySQL menampilkan format datetime yang berbeda dengan format default di Oracle. Untuk memformat ulang output, gunakan fungsi DATE_FORMAT().
SELECT LOCAL_TIMESTAMP FROM DUAL = 2019-01-01 10:01:01.0
CURRENT_DATE Menampilkan tanggal saat ini:
SELECT CURRENT_DATE FROM DUAL = 31-JAN-19
Menampilkan format datetime yang berbeda CURRENT_ DATE Fungsi di Cloud SQL untuk MySQL menampilkan format datetime yang berbeda. Untuk memformat ulang output, gunakan fungsi DATE_FORMAT().
SELECT CURRENT_DATE FROM DUAL = 2019-01-31
CURRENT_ TIMESTAMP Menampilkan tanggal dan waktu saat ini:
SELECT CURRENT_TIMESTAMP FROM DUAL = 31-JAN-19 06.54.35.543146 AM +00:00
Menampilkan format datetime yang berbeda CURRENT_ TIMESTAMP Fungsi di Cloud SQL untuk MySQL menampilkan format datetime yang berbeda. Untuk memformat ulang output, gunakan fungsi DATE_FORMAT().
SELECT CURRENT_TIMESTAMP FROM DUAL = 2019-01-31 06:55:07
ADD_MONTHS Menampilkan tanggal plus bulan dalam bilangan bulat:
ADD_MONTHS(SYSDATE, 1) = 31-JAN-19
Memerlukan nama fungsi yang berbeda ADDDATE Fungsi di Cloud SQL untuk MySQL menampilkan format datetime yang berbeda. Untuk memformat ulang output, gunakan fungsi DATE_FORMAT().
ADDDATE(SYSDATE(), 1) = 2019-08-01 06:42:49.0
EXTRACT (bagian tanggal) Menampilkan nilai kolom datetime berdasarkan ekspresi interval:
EXTRACT(YEAR FROM DATE '2019-01-31') = 2019
Ya EXTRACT (bagian tanggal) EXTRACT(YEAR FROM DATE '2019-01-31') = 2019
LAST_DAY Menampilkan hari terakhir bulan itu untuk tanggal tertentu:
LAST_DAY('01-JAN-2019') = 31-JAN-19
Sebagian LAST_DAY Fungsi di Cloud SQL untuk MySQL menampilkan format datetime yang berbeda dengan format default di Oracle. Untuk memformat ulang output, gunakan fungsi DATE_FORMAT().
LAST_DAY('2019-01-01') = 2019-01-31
MONTH_ BETWEEN Menampilkan jumlah bulan antara tanggal date1 dan date2 yang ditentukan:
MONTHS_BETWEEN( SYSDATE, SYSDATE-60) = 1.96
Sebagian PERIOD_DIFF Fungsi PERIOD_DIFF di Cloud SQL untuk MySQL menampilkan selisih bulan sebagai bilangan bulat antara dua periode (diformat sebagai YYMM atau YYYYMM):
PERIOD_DIFF( '201903', '201901') = 2
TO_CHAR (Datetime) Mengonversi jenis angka, datetime, atau stempel waktu menjadi jenis string
TO_CHAR( SYSDATE,'DD-MM-YYYY HH24:MI:SS') = 01-01-2019 10:01:01
Memerlukan nama fungsi yang berbeda DATE_FORMAT Fungsi DATE_FORMAT di Cloud SQL untuk MySQL memformat nilai tanggal sesuai dengan string format:
DATE_FORMAT( SYSDATE(),'%d-%m-%Y %H:%i:%s') 01-01-2019 10:01:01

Tabel berikut menjelaskan elemen fungsi encoding dan decoding di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
DECODE Membandingkan ekspresi dengan setiap nilai penelusuran satu per satu menggunakan fungsionalitas pernyataan IF-THEN-ELSE Tidak CASE Gunakan pernyataan CASE Cloud SQL untuk MySQL untuk fungsionalitas serupa
DUMP Menampilkan nilai VARCHAR2 yang berisi kode jenis data, panjang dalam byte, dan representasi internal ekspresi Tidak T/A Tidak didukung
ORA_HASH Menghitung nilai hash untuk ekspresi tertentu Tidak MD5 or SHA Gunakan fungsi MD5 untuk checksum 128-bit atau fungsi SHA untuk checksum 160-bit

Tabel berikut menjelaskan elemen fungsi konversi di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
CAST Mengonversi satu jenis data bawaan atau nilai berjenis koleksi menjadi jenis data bawaan atau nilai berjenis koleksi lainnya:
CAST('1' as int) + 1 = 2
Sebagian CAST Sesuaikan bergantung pada apakah konversi eksplisit atau implisit diperlukan:
CAST('1' AS SIGNED) + 1 = 2
CONVERT Mengonversi string karakter dari satu himpunan karakter ke himpunan karakter lainnya:
CONVERT ( 'Ä Ê Í Õ Ø A B C D E ', 'US7ASCII', 'WE8ISO8859P1') = ?? ?? ?? A B C
Sebagian CONVERT Fungsi CONVERT di Cloud SQL untuk MySQL memerlukan beberapa penyesuaian sintaksis dan parameter:
CONVERT( 'Ä Ê Í A B C ' USING utf8) = Ä Ê Í A B C
TO_CHAR (string/numerik) Fungsi ini mengonversi angka atau tanggal menjadi string:
TO_CHAR(22.73,'$99.9') = $22.7
Tidak FORMAT Fungsi FORMAT di Cloud SQL untuk MySQL mengonversi angka menjadi format seperti #,###,###.##, membulatkannya ke satu angka di belakang koma, lalu menampilkan hasilnya sebagai string:
CONCAT('$', FORMAT(22.73, 1)) = $22.7
TO_DATE Fungsi TO_DATE di Oracle mengonversi string menjadi tanggal berdasarkan format datetimecode:
TO_DATE( '2019/01/01', 'yyyy-mm-dd') = 01-JAN-2019
Memerlukan nama fungsi yang berbeda STR_TO_DATE Fungsi STR_TO_DATE di Cloud SQL untuk MySQL mengambil string dan menampilkan tanggal berdasarkan format datetime:
STR_TO_DATE( '2019/01/01', '%Y/%m/%d') = 2019-01-01
TO_NUMBER Mengonversi ekspresi menjadi nilai dengan jenis data NUMBER:
TO_NUMBER('01234') = 1234
Memerlukan nama fungsi yang berbeda CAST Gunakan fungsi CAST di Cloud SQL untuk MySQL untuk menampilkan hasil yang sama dengan fungsi TO_NUMBER di Oracle:
CAST('01234' as SIGNED) = 1234

Tabel berikut menjelaskan elemen fungsi SELECT bersyarat di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
CASE Pernyataan CASE memilih dari serangkaian kondisi dan menjalankan pernyataan yang terkait dengan sintaksis berikut:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END
Ya CASE Selain fungsi CASE, Cloud SQL untuk MySQL mendukung penggunaan penanganan bersyarat IF/ELSE di dalam pernyataan SELECT:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

Tabel berikut menjelaskan elemen fungsi null di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
COALESCE Menampilkan ekspresi bukan null pertama dalam daftar ekspresi:
COALESCE( null, '1', 'a') = a
Ya COALESCE COALESCE( null, '1', 'a') = 1
NULLIF Melakukan perbandingan antara expression1 dan expression2. Jika keduanya sama, fungsi akan menampilkan null. Jika tidak sama, fungsi akan menampilkan expression1:
NULLIF('1', '2') = a
Ya NULLIF NULLIF('1', '2') = a
NVL Mengganti nilai null dengan string dalam hasil kueri:
NVL(null, 'a') = a
Tidak IFNULL IFNULL(null, 'a') = a
NVL2 Menentukan nilai yang ditampilkan oleh kueri berdasarkan nilai ekspresi tertentu, yakni null atau bukan null. Tidak CASE Pernyataan CASE memilih dari serangkaian kondisi dan menjalankan pernyataan yang terkait:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

Tabel berikut menjelaskan elemen fungsi lingkungan dan ID di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
SYS_GUID Menghasilkan dan menampilkan ID unik global (nilai RAW) yang terdiri atas 16 byte:
SELECT SYS_GUID() FROM DUAL = 8EFA4A31468B4C6DE05011AC0200009E
Tidak REPLACE dan UUID Sebagai solusinya, gunakan fungsi REPLACE dan UUID untuk menyimulasikan fungsi SYS_GUID:
REPLACE( UUID(), '-', '')
UID Menampilkan bilangan bulat yang mengidentifikasi pengguna sesi secara unik (pengguna yang login):
SELECT UID FROM DUAL = 43
Tidak T/A T/A
USER Menampilkan nama pengguna dari pengguna yang terhubung ke sesi saat ini:
SELECT USER FROM DUAL = username
Ya USER + INSTR + SUBSTR Fungsi USER di Cloud SQL untuk MySQL menampilkan nama pengguna dan nama host (root@IP_ADDRESS) untuk koneksi tersebut. Untuk mengambil nama pengguna saja, gunakan fungsi pendukung tambahan:
SELECT SUBSTR(USER(), 1, INSTR(USER(), '@') -1) FROM DUAL = root
USERENV Menampilkan informasi tentang sesi Oracle saat ini, seperti bahasa sesi:
SELECT USERENV('LANGUAGE') FROM DUAL = ENGLISH_AMERICA. AL32UTF8
Tidak SHOW SESSION VARIABLES Pernyataan SHOW SESSION VARIABLES di Cloud SQL untuk MySQL menampilkan setelan untuk sesi saat ini:
SHOW SESSION VARIABLES LIKE '%collation%'; = utf8_general_ci
ROWID Oracle menetapkan ROWID unik ke setiap baris tabel untuk mengidentifikasi baris tersebut dalam tabel. ROWID adalah alamat baris yang berisi nomor objek data, blok data baris, posisi baris, dan file data. Sebagian T/A ROW_NUMBER() tersedia mulai di MySQL 8.0. Jika Anda menggunakan versi sebelumnya, emulasikan fungsionalitas yang sama menggunakan variabel sesi @row_number.
ROWNUM Menampilkan angka yang menunjukkan urutan ditampilkannya baris oleh tabel Oracle Sebagian T/A ROW_NUMBER() tersedia mulai di MySQL 8.0. Jika Anda menggunakan versi sebelumnya, emulasikan fungsionalitas yang sama menggunakan variabel sesi @row_number.

Tabel berikut menjelaskan elemen fungsi agregat (grup) di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
AVG Menampilkan nilai rata-rata kolom atau ekspresi Ya AVG Setara dengan Oracle
COUNT Menampilkan jumlah baris yang ditampilkan oleh kueri Ya COUNT Setara dengan Oracle
COUNT (DISTINCT) Menampilkan jumlah nilai unik dalam kolom atau ekspresi Ya COUNT (DISTINCT) Setara dengan Oracle
MAX Menampilkan nilai maksimum kolom atau ekspresi Ya MAX Setara dengan Oracle
MIN Menampilkan nilai minimum kolom atau ekspresi Ya MIN Setara dengan Oracle
SUM Menampilkan jumlah nilai kolom atau ekspresi Ya SUM Setara dengan Oracle
LISTAGG Mengurutkan data dalam setiap grup yang ditentukan dalam klausa ORDER BY dan menggabungkan nilai kolom pengukuran:
SELECT LISTAGG( DEPARTMENT_NAME, ', ') WITHIN GROUP (ORDER BY DEPARTMENT_NAME) DEPT FROM DEPARTMENTS; -- Single line results = Accounting, Administration, Benefits, Construction
Memerlukan sintaksis dan nama fungsi yang berbeda GROUP_ CONCAT Gunakan fungsi GROUP_CONCAT di Cloud SQL untuk MySQL untuk menampilkan hasil yang setara:
SELECT GROUP_CONCAT( DEPARTMENT_NAME ORDER BY DEPARTMENT_NAME SEPARATOR ', ') DEPT FROM DEPARTMENTS; -- Single line results = Accounting, Administration, Benefits, Construction

Tabel berikut menjelaskan elemen fungsi FETCH di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL Implementasi di Cloud SQL untuk MySQL
FETCH Mengambil sejumlah baris yang ditentukan dari kumpulan hasil kueri multi-baris:
SELECT * FROM EMPLOYEES FETCH FIRST 10 ROWS ONLY;
Ya LIMIT Gunakan klausa LIMIT MySQL untuk mengambil baris dari kueri:
SELECT * FROM EMPLOYEES LIMIT 10;

Pemfilteran, operator, dan subkueri dasar

Pemfilteran, fungsi operator, dan subkueri dasar relatif mudah dikonversi, tanpa perlu banyak upaya. Sebagian besar upaya berkisar pada pengonversian format tanggal karena Oracle dan Cloud SQL untuk MySQL menggunakan format tanggal default yang berbeda:

  • Fungsi SYSDATE di Oracle secara default menampilkan format 01-AUG-19.
  • Fungsi SYSDATE() di Cloud SQL untuk MySQL secara default menampilkan format 2019-08-01 12:04:05.

Untuk menetapkan format tanggal dan waktu, gunakan fungsi DATE_FORMAT atau STR_TO_DATE di MySQL.

Tabel berikut menjelaskan elemen fungsi pemfilteran, operator, dan subkueri dasar di Oracle dan Cloud SQL untuk MySQL yang setara berdasarkan nama dan fungsionalitas, dan elemen yang perlu dikonversi.

Fungsi di Oracle Implementasi di Oracle Setara dengan Cloud SQL untuk MySQL Fungsi di Cloud SQL untuk MySQL
EXISTS/ NOT EXISTS Ya EXISTS/ NOT EXISTS SELECT * FROM DEPARTMENTS D WHERE EXISTS (SELECT 1 FROM EMPLOYEES E WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID);
IN/NOT IN Ya 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 Ya LIKE/NOT LIKE SELECT * FROM EMPLOYEES WHERE FIRST_NAME LIKE '_e_n%';
BETWEEN/ NOT BETWEEN Ya BETWEEN/ NOT BETWEEN SELECT * FROM EMPLOYEES WHERE EXTRACT(YEAR FROM HIRE_DATE) NOT BETWEEN 2001 and 2004;
AND/OR Ya AND/OR SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID IN(100, 101) AND (SALARY >= 1000 OR HIRE_DATE <= '2006-02-05');
SubQuery Ya SubQuery Cloud SQL untuk MySQL mendukung subkueri dalam klausa SELECT, klausa JOIN, dan untuk pemfilteran dalam klausa 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);
Operator Ya Operator Cloud SQL untuk MySQL mendukung semua operator dasar:
> | >= | < | <= | = | <> | !=

Praktik terbaik untuk kueri Cloud SQL untuk MySQL

Untuk mempertahankan tingkat performa yang sebanding antara Cloud SQL untuk MySQL dan Oracle, Anda mungkin perlu mengoptimalkan kueri Anda. Pengoptimalan ini termasuk mengubah struktur indeks dan menyesuaikan skema database. Bagian ini memberikan beberapa panduan untuk membantu Anda mencapai performa kueri yang setara di Cloud SQL untuk MySQL.

Membuat indeks berkelompok

Saat menggunakan mesin penyimpanan InnoDB, salah satu praktik terbaiknya adalah menentukan tabel yang berisi kunci utama, karena kunci ini menghasilkan indeks berkelompok pada tabel tersebut. Selain meningkatkan performa kueri, pendekatan ini juga memungkinkan Anda membuat indeks sekunder tambahan. Namun, Anda sebaiknya tidak membuat terlalu banyak indeks. Indeks yang redundan tidak akan meningkatkan performa dan justru dapat memperlambat eksekusi DML. Praktik terbaik ini mengantarkan ke praktik terbaik kedua: pantau secara rutin untuk mendeteksi indeks yang redundan, dan jika hal itu terjadi, hapus indeks tersebut dari database.

Gunakan kueri berikut untuk mengidentifikasi tabel yang tidak memiliki kunci utama agar Anda dapat membuat kunci utama untuk tabel tersebut:

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';

Gunakan kueri berikut untuk menemukan tabel yang tidak memiliki indeks agar Anda dapat membuat indeks untuk tabel tersebut:

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';

Gunakan kueri berikut untuk mendeteksi keberadaan indeks yang redundan agar Anda dapat menghapus redundansi:

mysql> SELECT * FROM sys.schema_redundant_indexes;

Menyesuaikan parameter kueri

Untuk menyesuaikan performa kueri, Anda mungkin perlu menyesuaikan parameter sesi. Cloud SQL untuk MySQL memiliki sekumpulan flag yang dapat Anda ubah untuk keperluan ini, termasuk flag berikut:

  • Parameter terkait InnoDB
  • Parameter SORT
  • Parameter JOIN
  • Parameter penanganan cache

Memantau kueri

Kueri yang berjalan lambat dapat menyebabkan sistem berhenti merespons atau menimbulkan bottleneck lain, sehingga penting untuk memantau kueri secara rutin.

Ada beberapa cara untuk mendiagnosis pernyataan SQL yang berjalan lambat:

  • Gunakan dasbor Cloud SQL untuk MySQL untuk mendapatkan insight real-time dan historis tentang kueri yang berjalan lambat.
  • Gunakan Cloud Monitoring untuk memantau log kueri yang berjalan lambat di Cloud SQL untuk MySQL.
  • Gunakan tabel virtual statement_analysis di Cloud SQL untuk MySQL untuk melihat statistik runtime tentang pernyataan SQL:

    mysql> SELECT * FROM sys.statement_analysis;
    

Menganalisis kueri Cloud SQL untuk MySQL

Pengoptimal kueri di Cloud SQL untuk MySQL menghasilkan rencana eksekusi untuk pernyataan SELECT, INSERT, UPDATE, dan DELETE. Rencana ini berguna saat Anda menyesuaikan kueri yang berjalan lambat. Ada beberapa pertimbangan yang perlu diperhatikan:

  • Rencana eksekusi bukanlah objek database yang perlu dimigrasikan, melainkan alat untuk menganalisis perbedaan performa antara Oracle dan Cloud SQL untuk MySQL yang menjalankan pernyataan yang sama pada set data identik.
  • Cloud SQL untuk MySQL tidak mendukung sintaksis, fungsionalitas, atau output rencana eksekusi yang sama dengan Oracle.

Berikut adalah contoh rencana untuk menggambarkan perbedaan antara rencana eksekusi di Oracle dan di Cloud SQL untuk 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  |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+

Mengoptimalkan prosedur dan pemicu tersimpan

Tidak seperti di Oracle, prosedur dan fungsi tersimpan di Cloud SQL untuk MySQL diurai pada setiap eksekusi. Alat yang berguna untuk mengukur performa prosedur dan fungsi tersimpan adalah utilitas BENCHMARK() MySQL. Alat ini memerlukan dua parameter (jumlah iterasi dan ekspresi) dan memperkirakan runtime ekspresi yang ditentukan (misalnya prosedur, fungsi, dan pernyataan SELECT tersimpan). Outputnya menunjukkan perkiraan total runtime untuk semua iterasi.

Berikut adalah contoh untuk mengilustrasikan utilitas 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

Jika Anda melihat adanya regresi performa selama konversi, gunakan perintah EXPLAIN MySQL untuk mengidentifikasi faktor yang kemungkinan menyebabkan regresi tersebut. Salah satu solusi umum untuk masalah performa yang lambat adalah dengan mengubah struktur indeks tabel agar mengakomodasi pengoptimal MySQL. Praktik umum lainnya adalah mengoptimalkan kode PL/SQL yang telah dikonversi dengan mengurangi pengambilan data yang tidak perlu atau dengan menggunakan tabel sementara dalam kode MySQL prosedural.

Langkah berikutnya

  • Pelajari lebih lanjut akun pengguna MySQL.
  • Pelajari arsitektur referensi, diagram, dan praktik terbaik tentang Google Cloud. Lihat Cloud Architecture Center kami.