Convertir y optimizar consultas de Oracle Database a Cloud SQL para MySQL

En este documento se describen las diferencias básicas entre las consultas de Oracle® y Cloud SQL para MySQL, así como la correspondencia entre las funciones de Oracle y las de Cloud SQL para MySQL. También se describen las consideraciones sobre el rendimiento de Cloud SQL para MySQL y las formas de analizar y optimizar el rendimiento de las consultas enGoogle Cloud. Aunque en este documento se mencionan técnicas para optimizar los procedimientos almacenados y los activadores de Cloud SQL para MySQL, no se explica cómo traducir el código PL/SQL a procedimientos y funciones almacenados de MySQL.

Al convertir consultas de Oracle Database a Cloud SQL para MySQL, hay que tener en cuenta ciertas diferencias en el dialecto SQL. También hay varias funciones integradas que son diferentes o incompatibles entre las dos plataformas de bases de datos.

Diferencias entre las consultas básicas

Aunque tanto Oracle como Cloud SQL para MySQL admiten ANSI SQL, hay varias diferencias fundamentales a la hora de consultar datos, principalmente en lo que respecta al uso de funciones del sistema.

En la siguiente tabla se destacan las diferencias en la sintaxis de SELECT y FROM para Oracle y Cloud SQL para MySQL.

Nombre de la función de Oracle Implementación de Oracle Compatibilidad con Cloud SQL para MySQL Equivalente de Cloud SQL para MySQL
Sintaxis básica de SQL para obtener datos SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT para imprimir la salida SELECT 1 FROM DUAL SELECT 1
o
SELECT 1 FROM DUAL
Alias de columna SELECT COL1 AS C1 SELECT COL1 AS C1
o
SELECT COL1 C1
Distinción entre mayúsculas y minúsculas en los nombres de las tablas No distingue entre mayúsculas y minúsculas (por ejemplo, el nombre de la tabla puede ser orders y ORDERS). No Distinguen entre mayúsculas y minúsculas según el nombre de tabla definido (por ejemplo, el nombre de tabla solo puede ser orders o ORDERS).

Vistas insertadas

Las vistas insertadas (también conocidas como tablas derivadas) son instrucciones SELECT que se encuentran en la cláusula FROM y se usan como subconsultas. Las vistas insertadas pueden simplificar las consultas complejas, ya que eliminan los cálculos compuestos o las operaciones de unión, y condensan varias consultas independientes en una sola consulta simplificada.

En el siguiente ejemplo se muestra una conversión de Oracle 11g/12c a Cloud SQL para MySQL de una vista insertada.

Una vista insertada en Oracle 11g/12c:

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

Una vista de trabajo en Cloud SQL para MySQL 5.7 con un alias:

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

Uniones

Cloud SQL para MySQL admite los tipos de unión de Oracle, excepto FULL JOIN. Las uniones de Cloud SQL para MySQL admiten el uso de sintaxis alternativas, como la cláusula USING, la cláusula WHERE en lugar de la cláusula ON y la SUBQUERY en la instrucción JOIN.

En la siguiente tabla se muestra un ejemplo de conversión de JOIN.

Tipo de JOIN de Oracle Compatibilidad con Cloud SQL para MySQL Sintaxis de JOIN de Cloud SQL para MySQL
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 No Considera usar UNION con LEFT y 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;

Aunque Cloud SQL para MySQL admite las funciones UNION y UNION ALL, no admite las funciones INTERSECT y MINUS de Oracle:

  • UNION adjunta los conjuntos de resultados de dos instrucciones SELECT después de eliminar los registros duplicados.
  • UNION ALL adjunta los conjuntos de resultados de dos instrucciones SELECT sin eliminar los registros duplicados.
  • INTERSECT devuelve la intersección de dos instrucciones SELECT solo si existe un registro en los conjuntos de resultados de ambas consultas.
  • MINUS compara dos o más instrucciones SELECT y devuelve solo las filas distintas de la primera consulta que no devuelve la segunda.

En la siguiente tabla se muestran algunos ejemplos de conversión de Oracle a Cloud SQL para MySQL.

Función de Oracle Implementación de Oracle Compatibilidad con Cloud SQL para MySQL Equivalente de Cloud SQL para 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
No SELECT COL1 FROM TBL1
WHERE COL1 IN
(SELECT COL1 FROM TBL2)
MINUS SELECT COL1 FROM TBL1
MINUS
SELECT COL1 FROM TBL2
No SELECT A.COL1 FROM TBL1 A LEFT JOIN TBL2 B ON USING(COL1) WHERE B.COL1 IS NULL

Funciones escalares y de grupo

Cloud SQL para MySQL ofrece una amplia lista de funciones escalares (de una sola fila) y de agregación. Algunas funciones de Cloud SQL para MySQL son similares a sus equivalentes de Oracle (por nombre y funcionalidad, o con un nombre diferente pero con una funcionalidad similar). Aunque algunas funciones de Cloud SQL para MySQL pueden tener nombres idénticos a sus equivalentes de Oracle, también pueden mostrar funcionalidades diferentes.

En la siguiente tabla se describe en qué casos las funciones de caracteres de Oracle y Cloud SQL para MySQL son equivalentes por nombre y funcionalidad, y en qué casos se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
CONCAT Devuelve la primera cadena concatenada con la segunda:
CONCAT('A', 1) = A1
CONCAT CONCAT('A', 1) = A1
CONCAT USING PIPE FNAME |' '| LNAME No CONCAT CONCAT(FNAME, ' ', LNAME)
LOWER o UPPER Devuelve la cadena con todas las letras en minúsculas o en mayúsculas:
LOWER('SQL') = sql
LOWER o UPPER LOWER('SQL') = sql
LPAD/RPAD Devuelve expression1, con un relleno a la izquierda o a la derecha hasta alcanzar una longitud de n caracteres con la secuencia de caracteres de expression2:
LPAD('A',3,'*') = **A
LPAD o RPAD LPAD('A',3,'*') = **A
SUBSTR Devuelve una parte de la cadena, empezando por la posición x (en este caso, 3) y con una longitud de y. La primera posición de la cadena es 1.
SUBSTR('MySQL', 3, 3) = SQL
SUBSTR SUBSTR('MySQL', 3, 3) = SQL
INSTR Devuelve la posición (índice) de una cadena en otra cadena:
INSTR('MySQL', 'y') = 2
INSTR INSTR('MySQL', 'y') = 2
REPLACE Devuelve una cadena en la que cada instancia de una cadena de búsqueda se ha sustituido por una cadena de sustitución:
REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
REPLACE REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
TRIM Recortar los caracteres iniciales o finales (o ambos) de una cadena:
TRIM(both '-' FROM '-MySQL-') = MySQL TRIM(' MySQL ') = MySQL
TRIM TRIM(both '-' FROM '-MySQL-') = MySQL TRIM(' MySQL ') = MySQL
LTRIM/RTRIM Elimina de la parte izquierda o derecha de una cadena todos los caracteres que aparezcan en la búsqueda:
LTRIM(' MySQL', ' ') = MySQL
Parcialmente LTRIM or RTRIM Las funciones LTRIM y RTRIM de Oracle usan un segundo parámetro que especifica qué caracteres iniciales o finales se deben quitar de la cadena. Las funciones de Cloud SQL para MySQL solo eliminan los espacios en blanco iniciales y finales de la cadena dada:
LTRIM(' MySQL') = MySQL
ASCII Toma un solo carácter y devuelve su código ASCII numérico:
ASCII('A') = 65
ASCII ASCII('A') = 65
CHR Devuelve el valor del código ASCII, que es un valor numérico del 0 al 225, de un carácter:
CHR(65) = A
Requiere un nombre de función diferente CHAR Cloud SQL para MySQL usa la función CHAR para la misma función, por lo que debes cambiar el nombre de la función:
CHAR(65) = A
LENGTH Devuelve la longitud de una cadena determinada:
LENGTH('MySQL') = 5
LENGTH LENGTH('MySQL') = 5
REGEXP_REPLACE Busca en una cadena un patrón de expresión regular:
REGEXP_REPLACE('John', '[hn].', 'e') = Joe
No N/A Compatible a partir de la versión 8 de MySQL. Como solución alternativa, utiliza la función REPLACE si es posible o mueve la lógica a la capa de aplicación.
REGEXP_SUBSTR Amplía la funcionalidad de la función SUBSTR buscando una cadena con un patrón de expresión regular:
REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?') = https://console.cloud.google.com/
No N/A Compatible a partir de la versión 8 de MySQL. Como solución alternativa, utiliza la función SUBSTR si es posible o mueve la lógica a la capa de aplicación.
REGEXP_COUNT Devuelve el número de veces que aparece un patrón en una cadena de origen. No N/A No hay ninguna función equivalente disponible en Cloud SQL para MySQL. Mueve esta lógica a la capa de aplicación.
REGEXP_INSTR Buscar la posición (índice) de una cadena en un patrón de expresión regular No N/A Compatible a partir de la versión 8 de MySQL. Si usas una versión anterior, mueve esta lógica a la capa de aplicación.
REVERSE Devuelve la cadena invertida de una cadena determinada:
REVERSE('MySQL') = LQSyM
REVERSE REVERSE('MySQL') = LQSyM

En la siguiente tabla se describe dónde son equivalentes por nombre y funcionalidad las funciones numéricas de Oracle y Cloud SQL para MySQL, y dónde se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
ABS Devuelve el valor absoluto de un número determinado:
ABS(-4.6) = 4.6
ABS ABS(-4.6) = 4.6
CEIL Devuelve el menor número entero que sea mayor o igual que el número dado:
CEIL(21.4) = 22
CEIL CEIL(21.4) = 22
FLOOR Devuelve el número entero más grande que sea igual o inferior al número dado:
FLOOR(-23.7) = -24
FLOOR FLOOR(-23.7) = -24
MOD Devuelve el resto de m dividido entre n:
MOD(10, 3) = 1
MOD MOD(10, 3) = 1
ROUND Devuelve n redondeado a los enteros situados a la derecha de la coma decimal:
ROUND(1.39, 1) = 1.4
ROUND ROUND(1.39, 1) = 1.4
TRUNC(número) Devuelve n1 truncado a n2 decimales. El segundo parámetro es opcional.
TRUNC(99.999) = 99 TRUNC(99.999, 0) = 99
Requiere un nombre de función diferente TRUNCATE(número) La función de Cloud SQL para MySQL tiene un nombre diferente y el segundo parámetro es obligatorio.
TRUNCATE(99.999, 0) = 99

En la siguiente tabla se describe dónde son equivalentes las funciones de Oracle y Cloud SQL para MySQL datetime por nombre y funcionalidad, y dónde se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
SYSDATE Devuelve la fecha y la hora actuales definidas en el sistema operativo en el que reside el servidor de la base de datos:
SELECT SYSDATE FROM DUAL; = 31-JUL-2019
SYSDATE()

Cloud SQL para MySQL SYSDATE() debe incluir paréntesis y devuelve de forma predeterminada un formato datetime diferente al de la función SYSDATE de Oracle:

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

Puedes cambiar el datetime formato a nivel de sesión

SYSTIMESTAMP Devuelve la fecha del sistema, incluidos los segundos fraccionarios y la zona horaria:
SELECT SYSTIMESTAMP FROM DUAL = 01-JAN-19 07.37.11.622187000 AM +00:00
Requiere un nombre de función diferente CURRENT_ TIMESTAMP La función de Cloud SQL para MySQL devuelve un formato datetime diferente de forma predeterminada. Para cambiar el formato de la salida, usa la función DATE_FORMAT().
SELECT CURRENT_TIMESTAMP FROM DUAL; = 2019-01-31 06:55:07
LOCAL_ TIMESTAMP Devuelve la fecha y la hora actuales como un tipo TIMESTAMP:
SELECT LOCALTIMESTAMP FROM DUAL = 01-JAN-19 10.01.10.123456 PM
Devuelve un formato datetime diferente LOCAL_ TIMESTAMP La función de Cloud SQL para MySQL devuelve un formato datetime distinto del formato predeterminado de Oracle. Para cambiar el formato de la salida, usa la función DATE_FORMAT().
SELECT LOCAL_TIMESTAMP FROM DUAL = 2019-01-01 10:01:01.0
CURRENT_DATE Devuelve la fecha actual:
SELECT CURRENT_DATE FROM DUAL = 31-JAN-19
Devuelve un formato datetime diferente CURRENT_ DATE La función de Cloud SQL para MySQL devuelve un formato datetime diferente. Para cambiar el formato de la salida, usa la función DATE_FORMAT().
SELECT CURRENT_DATE FROM DUAL = 2019-01-31
CURRENT_ TIMESTAMP Devuelve la fecha y la hora actuales:
SELECT CURRENT_TIMESTAMP FROM DUAL = 31-JAN-19 06.54.35.543146 AM +00:00
Devuelve un formato datetime diferente CURRENT_ TIMESTAMP La función de Cloud SQL para MySQL devuelve un formato datetime diferente. Para cambiar el formato de la salida, usa la función DATE_FORMAT().
SELECT CURRENT_TIMESTAMP FROM DUAL = 2019-01-31 06:55:07
ADD_MONTHS Devuelve la fecha más los meses enteros:
ADD_MONTHS(SYSDATE, 1) = 31-JAN-19
Requiere un nombre de función diferente ADDDATE La función de Cloud SQL para MySQL devuelve un formato datetime diferente. Para cambiar el formato de la salida, usa la función DATE_FORMAT().
ADDDATE(SYSDATE(), 1) = 2019-08-01 06:42:49.0
EXTRACT (parte de la fecha) Devuelve el valor de un campo datetime en función de una expresión de intervalo:
EXTRACT(YEAR FROM DATE '2019-01-31') = 2019
EXTRACT (parte de la fecha) EXTRACT(YEAR FROM DATE '2019-01-31') = 2019
LAST_DAY Devuelve el último día del mes de una fecha determinada:
LAST_DAY('01-JAN-2019') = 31-JAN-19
Parcialmente LAST_DAY La función de Cloud SQL para MySQL devuelve un formato datetime distinto del formato predeterminado de Oracle. Para cambiar el formato de la salida, usa la función DATE_FORMAT().
LAST_DAY('2019-01-01') = 2019-01-31
MONTH_ BETWEEN Devuelve el número de meses entre las fechas date1 y date2:
MONTHS_BETWEEN( SYSDATE, SYSDATE-60) = 1.96
Parcialmente PERIOD_DIFF La función PERIOD_DIFF de Cloud SQL para MySQL devuelve la diferencia en meses como un número entero entre dos periodos (con el formato YYMM o YYYYMM):
PERIOD_DIFF( '201903', '201901') = 2
TO_CHAR (Datetime) Convierte un número, datetime o una marca de tiempo en un tipo de cadena.
TO_CHAR( SYSDATE,'DD-MM-YYYY HH24:MI:SS') = 01-01-2019 10:01:01
Requiere un nombre de función diferente DATE_FORMAT La función DATE_FORMAT de Cloud SQL para MySQL
da formato a un valor de fecha según una cadena de formato: DATE_FORMAT( SYSDATE(),'%d-%m-%Y %H:%i:%s') 01-01-2019 10:01:01

En la siguiente tabla se describe en qué casos las funciones de codificación y decodificación de Oracle y Cloud SQL para MySQL son equivalentes por nombre y funcionalidad, y en qué casos se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
DECODE Compara la expresión con cada valor de búsqueda uno por uno mediante la funcionalidad de una instrucción IF-THEN-ELSE. No CASE Usa la instrucción CASE de Cloud SQL para MySQL para obtener una funcionalidad similar
DUMP Devuelve un valor VARCHAR2 que contiene el código del tipo de datos, la longitud en bytes y la representación interna de la expresión. No N/A No compatible
ORA_HASH Calcula el valor hash de una expresión determinada. No MD5 or SHA Usa la función MD5 para las sumas de comprobación de 128 bits o la función SHA para las sumas de comprobación de 160 bits.

En la siguiente tabla se describe en qué casos las funciones de conversión de Oracle y Cloud SQL para MySQL son equivalentes por nombre y funcionalidad, y en qué casos se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
CAST Convierte un tipo de datos integrado o un valor de tipo colección en otro tipo de datos integrado o valor de tipo colección:
CAST('1' as int) + 1 = 2
Parcialmente CAST Ajusta el valor en función de si se requiere una conversión explícita o implícita:
CAST('1' AS SIGNED) + 1 = 2
CONVERT Convierte una cadena de caracteres de un conjunto de caracteres a otro:
CONVERT ( 'Ä Ê Í Õ Ø A B C D E ', 'US7ASCII', 'WE8ISO8859P1') = ?? ?? ?? A B C
Parcialmente CONVERT La función CONVERT de Cloud SQL para MySQL requiere algunos ajustes en la sintaxis y los parámetros:
CONVERT( 'Ä Ê Í A B C ' USING utf8) = Ä Ê Í A B C
TO_CHAR (cadena o numérico) La función convierte un número o una fecha en una cadena:
TO_CHAR(22.73,'$99.9') = $22.7
No FORMAT La función FORMAT de Cloud SQL para MySQL convierte un número a un formato como #,###,###.##, lo redondea a un decimal y, a continuación, devuelve el resultado como una cadena:
CONCAT('$', FORMAT(22.73, 1)) = $22.7
TO_DATE La función TO_DATE de Oracle convierte una cadena en una fecha según un formato datetimecode:
TO_DATE( '2019/01/01', 'yyyy-mm-dd') = 01-JAN-2019
Requiere un nombre de función diferente STR_TO_DATE La función Cloud SQL para MySQL STR_TO_DATE toma una cadena y devuelve una fecha basada en un formato datetime:
STR_TO_DATE( '2019/01/01', '%Y/%m/%d') = 2019-01-01
TO_NUMBER Convierte una expresión en un valor de tipo de datos NUMBER:
TO_NUMBER('01234') = 1234
Requiere un nombre de función diferente CAST Usa la función CAST de Cloud SQL para MySQL para devolver el mismo resultado que la función TO_NUMBER de Oracle:
CAST('01234' as SIGNED) = 1234

En la siguiente tabla se describe dónde son equivalentes por nombre y funcionalidad las funciones condicionales SELECT de Oracle y Cloud SQL para MySQL, y dónde se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
CASE La instrucción CASE elige entre una secuencia de condiciones y ejecuta una instrucción correspondiente con la siguiente sintaxis:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END
CASE Además de la función CASE, Cloud SQL para MySQL admite el uso de IF/ELSE gestión condicional dentro de la instrucción SELECT:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

En la siguiente tabla se describe en qué casos las funciones nulas de Oracle y Cloud SQL para MySQL son equivalentes por nombre y funcionalidad, y en qué casos se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
COALESCE Devuelve la primera expresión no nula de la lista de expresiones:
COALESCE( null, '1', 'a') = a
COALESCE COALESCE( null, '1', 'a') = 1
NULLIF Compara expression1 y expression2. Si son iguales, la función devuelve null. Si no son iguales, la función devuelve expression1:
NULLIF('1', '2') = a
NULLIF NULLIF('1', '2') = a
NVL Sustituye un valor null por una cadena en los resultados de una consulta:
NVL(null, 'a') = a
No IFNULL IFNULL(null, 'a') = a
NVL2 Determina el valor devuelto por una consulta en función de si una expresión es nula o no nula. No CASE La instrucción CASE elige entre una secuencia de condiciones y ejecuta una instrucción correspondiente:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

En la siguiente tabla se describe dónde son equivalentes por nombre y funcionalidad las funciones de entorno e identificador de Oracle y Cloud SQL para MySQL, y dónde se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
SYS_GUID Genera y devuelve un identificador único global (valor RAW) compuesto por 16 bytes:
SELECT SYS_GUID() FROM DUAL = 8EFA4A31468B4C6DE05011AC0200009E
No REPLACE y UUID Como solución alternativa, usa las funciones REPLACE y UUID para simular la función SYS_GUID:
REPLACE( UUID(), '-', '')
UID Devuelve un número entero que identifica de forma única al usuario de la sesión (el usuario que ha iniciado sesión):
SELECT UID FROM DUAL = 43
No N/A N/A
USER Devuelve el nombre de usuario del usuario que está conectado a la sesión actual:
SELECT USER FROM DUAL = username
USER + INSTR + SUBSTR La función USER de Cloud SQL para MySQL devuelve el nombre de usuario y el nombre de host (root@IP_ADDRESS) de la conexión. Para obtener solo el nombre de usuario, usa las funciones de asistencia adicionales:
SELECT SUBSTR(USER(), 1, INSTR(USER(), '@') -1) FROM DUAL = root
USERENV Devuelve información sobre la sesión de Oracle actual, como el idioma de la sesión:
SELECT USERENV('LANGUAGE') FROM DUAL = ENGLISH_AMERICA. AL32UTF8
No SHOW SESSION VARIABLES La instrucción SHOW SESSION VARIABLES de Cloud SQL para MySQL devuelve los ajustes de la sesión actual:
SHOW SESSION VARIABLES LIKE '%collation%'; = utf8_general_ci
ROWID Oracle asigna a cada fila de una tabla un ROWID único para identificarla. ROWID es la dirección de la fila que contiene el número del objeto de datos, el bloque de datos de la fila, la posición de la fila y el archivo de datos. Parcialmente N/A ROW_NUMBER() está disponible a partir de MySQL 8.0. Si usas una versión anterior, emula la misma función con una variable de sesión @row_number.
ROWNUM Devuelve un número que representa el orden en el que una fila se devuelve de una tabla de Oracle. Parcialmente N/A ROW_NUMBER() está disponible a partir de MySQL 8.0. Si utilizas una versión anterior, emula la misma función usando una variable de sesión @row_number.

En la siguiente tabla se describe dónde son equivalentes las funciones de agregado (grupo) de Oracle y Cloud SQL para MySQL por nombre y funcionalidad, y dónde se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
AVG Devuelve el valor medio de una columna o una expresión. AVG Equivalente a Oracle
COUNT Devuelve el número de filas devueltas por una consulta. COUNT Equivalente a Oracle
COUNT (DISTINCT) Devuelve el número de valores únicos de la columna o expresión. COUNT (DISTINCT) Equivalente a Oracle
MAX Devuelve el valor máximo de una columna o expresión. MAX Equivalente a Oracle
MIN Devuelve el valor mínimo de una columna o una expresión. MIN Equivalente a Oracle
SUM Devuelve la suma de un valor de una columna o expresión. SUM Equivalente a Oracle
LISTAGG Ordena los datos de cada grupo especificado en la cláusula ORDER BY y concatena los valores de la columna de medida:
SELECT LISTAGG( DEPARTMENT_NAME, ', ') WITHIN GROUP (ORDER BY DEPARTMENT_NAME) DEPT FROM DEPARTMENTS; -- Single line results = Accounting, Administration, Benefits, Construction
Requiere un nombre de función y una sintaxis diferentes GROUP_ CONCAT Usa la función GROUP_CONCAT de Cloud SQL para MySQL para devolver resultados equivalentes:
SELECT GROUP_CONCAT( DEPARTMENT_NAME ORDER BY DEPARTMENT_NAME SEPARATOR ', ') DEPT FROM DEPARTMENTS; -- Single line results = Accounting, Administration, Benefits, Construction

En la siguiente tabla se describe dónde la función FETCH de Oracle y Cloud SQL para MySQL es equivalente por nombre y funcionalidad.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para MySQL Implementación de Cloud SQL para MySQL
FETCH Obtiene un número específico de filas del conjunto de resultados de una consulta de varias filas:
SELECT * FROM EMPLOYEES FETCH FIRST 10 ROWS ONLY;
LIMIT Usa la cláusula LIMIT de MySQL para obtener filas de una consulta:
SELECT * FROM EMPLOYEES LIMIT 10;

Filtrado básico, operadores y subconsultas

La conversión de los filtros básicos, las funciones de operador y las subconsultas es relativamente sencilla y requiere un esfuerzo mínimo. La mayor parte del trabajo se centra en convertir formatos de fecha, ya que Oracle y Cloud SQL para MySQL usan formatos de fecha predeterminados diferentes:

  • La función SYSDATE de Oracle devuelve este formato de forma predeterminada: 01-AUG-19.
  • La función SYSDATE() de Cloud SQL para MySQL devuelve este formato de forma predeterminada: 2019-08-01 12:04:05.

Para definir los formatos de fecha y hora, usa las funciones de MySQL DATE_FORMAT o STR_TO_DATE.

En la siguiente tabla se describe dónde son equivalentes por nombre y funcionalidad las funciones de filtrado básico, los operadores y las subconsultas de Oracle y Cloud SQL para MySQL, y dónde se recomienda una conversión.

Función de Oracle Implementación de Oracle Equivalente de Cloud SQL para MySQL Función de Cloud SQL para 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 para MySQL admite subconsultas en la cláusula SELECT , en la cláusula JOIN y para filtrar en las cláusulas 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);
Operadores Operadores Cloud SQL para MySQL admite todos los operadores básicos:
> | >= | < | <= | = | <> | !=

Prácticas recomendadas para las consultas de Cloud SQL para MySQL

Para mantener niveles de rendimiento comparables entre Cloud SQL para MySQL y Oracle, es posible que tengas que optimizar tus consultas. Estas optimizaciones incluyen cambiar las estructuras de los índices y ajustar el esquema de la base de datos. En esta sección se ofrecen algunas directrices para ayudarte a conseguir un rendimiento de las consultas comparable en Cloud SQL para MySQL.

Crear un índice de clúster

Cuando se usa el motor de almacenamiento InnoDB, se recomienda definir una tabla con una clave principal, ya que esta clave crea un índice agrupado en esa tabla. Además de mejorar el rendimiento de las consultas, este enfoque también te permite crear índices secundarios adicionales. Sin embargo, no es recomendable crear demasiados índices. Tener índices redundantes no mejora el rendimiento y puede ralentizar la ejecución de DML. Esta práctica recomendada lleva a otra: monitorizar periódicamente los índices redundantes y, si hay alguno, eliminarlo de la base de datos.

Usa la siguiente consulta para identificar las tablas que no tienen claves principales y, así, poder crearlas:

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

Usa la siguiente consulta para encontrar tablas que no tengan índices y, así, poder crearlos:

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

Usa la siguiente consulta para buscar índices redundantes y poder eliminarlos:

mysql> SELECT * FROM sys.schema_redundant_indexes;

Ajustar los parámetros de consulta

Para optimizar el rendimiento de las consultas, puede que tengas que ajustar los parámetros de sesión. Cloud SQL para MySQL tiene un conjunto de marcas que puedes modificar para este fin, incluidas las siguientes:

  • Parámetros relacionados con InnoDB
  • SORT parámetros
  • JOIN parámetros
  • Parámetros de gestión de la caché

Monitorizar consultas

Las consultas lentas pueden provocar que el sistema deje de responder o que se produzcan otros cuellos de botella, por lo que es importante monitorizar las consultas con regularidad.

Hay varias formas de diagnosticar las instrucciones SQL que se ejecutan lentamente:

  • Usa el panel de control de Cloud SQL para MySQL para obtener información valiosa en tiempo real y del historial sobre las consultas que se ejecutan lentamente.
  • Usa Cloud Monitoring para monitorizar el registro de consultas lentas de Cloud SQL para MySQL.
  • Usa la vista statement_analysisCloud SQL para MySQL para ver las estadísticas de tiempo de ejecución de una instrucción SQL:

    mysql> SELECT * FROM sys.statement_analysis;
    

Analizar consultas de Cloud SQL para MySQL

El optimizador de consultas de Cloud SQL para MySQL genera un plan de ejecución para las instrucciones SELECT, INSERT, UPDATE y DELETE. Estos planes son útiles cuando ajustas una consulta que se ejecuta lentamente. Debe tener en cuenta algunas consideraciones:

  • Los planes de ejecución no son objetos de base de datos que deban migrarse, sino una herramienta para analizar las diferencias de rendimiento entre Oracle y Cloud SQL para MySQL al ejecutar la misma instrucción en conjuntos de datos idénticos.
  • Cloud SQL para MySQL no admite la misma sintaxis, funcionalidad ni salida del plan de ejecución que Oracle.

Aquí tienes un plan de ejemplo para ilustrar las diferencias entre un plan de ejecución de Oracle y un plan de ejecución de Cloud SQL para 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  |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+

Optimizar los procedimientos almacenados y los activadores

A diferencia de Oracle, los procedimientos almacenados y las funciones de Cloud SQL para MySQL se analizan en cada ejecución. Una herramienta útil para comparar el rendimiento de los procedimientos y las funciones almacenados es la utilidad MySQL BENCHMARK(). Esta herramienta usa dos parámetros: un recuento de iteraciones y una expresión. Además, estima el tiempo de ejecución de la expresión dada (por ejemplo, un procedimiento almacenado, una función y una instrucción SELECT). El resultado representa el tiempo de ejecución total aproximado de todas las iteraciones.

A continuación, se muestra un ejemplo para ilustrar la utilidad 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

Si detectas una regresión del rendimiento durante la conversión, usa el comando MySQL EXPLAIN para identificar los posibles factores que contribuyen a la regresión. Una solución habitual para mejorar el rendimiento es modificar la estructura del índice de una tabla para adaptarla al optimizador de MySQL. Otra práctica habitual es optimizar el código PL/SQL convertido reduciendo la recuperación de datos innecesarios o usando tablas temporales en el código de procedimiento de MySQL.

Siguientes pasos

  • Consulta más información sobre las cuentas de usuario de MySQL.
  • Consulta arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Centro de arquitectura de Cloud.