Converter e otimizar consultas da base de dados Oracle para o Cloud SQL para MySQL

Este documento aborda as diferenças básicas de consultas entre o Oracle® e o Cloud SQL para MySQL, e como as funcionalidades no Oracle são mapeadas para as funcionalidades no Cloud SQL para MySQL. Também descreve considerações de desempenho para o Cloud SQL para MySQL e formas de analisar e otimizar o desempenho das consultas noGoogle Cloud. Embora este documento aborde técnicas para otimizar procedimentos armazenados e acionadores para o Cloud SQL para MySQL, não aborda como traduzir código PL/SQL para procedimentos e funções armazenados do MySQL.

Quando converte consultas da base de dados Oracle para o Cloud SQL para MySQL, existem determinadas diferenças no dialeto SQL a ter em conta. Também existem várias funções incorporadas que são diferentes ou incompatíveis entre as duas plataformas de base de dados.

Diferenças básicas entre consultas

Embora o Oracle e o Cloud SQL para MySQL suportem o ANSI SQL, existem várias diferenças fundamentais ao consultar dados, principalmente em torno da utilização de funções do sistema.

A tabela seguinte realça as diferenças na sintaxe SELECT e FROM para o Oracle e o Cloud SQL para MySQL.

Nome da funcionalidade da Oracle Implementação da Oracle Suporte do Cloud SQL para MySQL Equivalente do Cloud SQL para MySQL
Sintaxe básica de SQL para obtenção de dados SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
Sim SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT para impressão de saída SELECT 1 FROM DUAL Sim SELECT 1
ou
SELECT 1 FROM DUAL
Aliases das colunas SELECT COL1 AS C1 Sim SELECT COL1 AS C1
ou
SELECT COL1 C1
Sensibilidade a maiúsculas e minúsculas do nome da tabela Não é sensível a maiúsculas e minúsculas (por exemplo, o nome da tabela pode ser orders e ORDERS) Não Sensível a maiúsculas e minúsculas de acordo com o nome da tabela definido (por exemplo, o nome da tabela só pode ser orders ou ORDERS)

Visualizações inline

As vistas inline (também conhecidas como tabelas derivadas) são declarações SELECT, localizadas na cláusula FROM e usadas como uma subconsulta. As vistas inline podem ajudar a simplificar as consultas complexas removendo cálculos compostos ou eliminando operações de junção, ao mesmo tempo que condensam várias consultas separadas numa única consulta simplificada.

O exemplo seguinte descreve um exemplo de conversão do Oracle 11g/12c para o Cloud SQL for MySQL para uma vista inline.

Uma vista inline no Oracle 11g/12c:

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

Uma vista funcional no Cloud SQL para MySQL 5.7 com um alias:

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

Aderir

Os tipos de junção da Oracle são suportados pelo Cloud SQL para MySQL, exceto o FULL JOIN. As junções do Cloud SQL para MySQL suportam a utilização de sintaxe alternativa, como a cláusula USING, a cláusula WHERE em vez da cláusula ON e a cláusula SUBQUERY na declaração JOIN.

A tabela seguinte mostra um JOIN exemplo de conversão.

Oracle JOIN tipo Suporte do Cloud SQL para MySQL Sintaxe do Cloud SQL para MySQL JOIN
INNER JOIN Sim SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E JOIN DEPARTMENTS D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
CROSS JOIN Sim SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E CROSS JOIN DEPARTMENTS D
FULL JOIN Não Considere usar UNION com LEFT e 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 ] Sim SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
RIGHT JOIN [ OUTER ] Sim SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E RIGHT JOIN DEPARTMENTS D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
SUBQUERY Sim SELECT E.FIRST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E JOIN (SELECT * FROM DEPARTMENTS)D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

Embora o Cloud SQL para MySQL suporte as funções UNION e UNION ALL, não suporta as funções INTERSECT e MINUS da Oracle:

  • UNION anexa os conjuntos de resultados de duas declarações SELECT depois de eliminar os registos duplicados.
  • UNION ALL anexa os conjuntos de resultados de duas declarações SELECT sem eliminar registos duplicados.
  • INTERSECT devolve a interseção de duas declarações SELECT, apenas se existir um registo nos conjuntos de resultados de ambas as consultas.
  • MINUS compara duas ou mais declarações SELECT, devolvendo apenas linhas distintas da primeira consulta que não são devolvidas pela segunda consulta.

A tabela seguinte mostra alguns exemplos de conversão do Oracle para o Cloud SQL para MySQL.

Função Oracle Implementação da Oracle Suporte do Cloud SQL para MySQL Equivalente do Cloud SQL para MySQL
UNION SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
Sim SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
UNION ALL SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
Sim SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
INTERSECT SELECT COL1 FROM TBL1
INTERSECT
SELECT COL1 FROM TBL2
Não SELECT COL1 FROM TBL1
WHERE COL1 IN
(SELECT COL1 FROM TBL2)
MINUS SELECT COL1 FROM TBL1
MINUS
SELECT COL1 FROM TBL2
Não SELECT A.COL1 FROM TBL1 A LEFT JOIN TBL2 B ON USING(COL1) WHERE B.COL1 IS NULL

Funções escalares e de grupo

O Cloud SQL para MySQL oferece uma extensa lista de funções escalares (de linha única) e de agregação. Algumas das funções do Cloud SQL para MySQL são semelhantes às respetivas equivalentes do Oracle (por nome e funcionalidade ou com um nome diferente, mas com uma funcionalidade semelhante). Embora algumas funções do Cloud SQL para MySQL possam ter nomes idênticos aos das respetivas contrapartes Oracle, também podem apresentar funcionalidades diferentes.

A tabela seguinte descreve onde as funções de carateres do Oracle e do Cloud SQL for MySQL são equivalentes por nome e funcionalidade, e onde se recomenda uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
CONCAT Devolve a primeira string concatenada com a segunda string:
CONCAT('A', 1) = A1
Sim CONCAT CONCAT('A', 1) = A1
CONCAT USING PIPE FNAME |' '| LNAME Não CONCAT CONCAT(FNAME, ' ', LNAME)
LOWER ou UPPER Devolve a string com todas as letras em minúsculas ou maiúsculas:
LOWER('SQL') = sql
Sim LOWER ou UPPER LOWER('SQL') = sql
LPAD/RPAD Devolve expression1, com preenchimento à esquerda ou à direita até ter n carateres com a sequência de carateres em expression2:
LPAD('A',3,'*') = **A
Sim LPAD ou RPAD LPAD('A',3,'*') = **A
SUBSTR Devolve uma parte da string, começando na posição x (neste caso, 3), com um comprimento de y. A primeira posição na string é 1.
SUBSTR('MySQL', 3, 3) = SQL
Sim SUBSTR SUBSTR('MySQL', 3, 3) = SQL
INSTR Devolve a posição (índice) de uma string a partir de uma determinada string:
INSTR('MySQL', 'y') = 2
Sim INSTR INSTR('MySQL', 'y') = 2
REPLACE Devolve uma string com todas as ocorrências de uma string de pesquisa substituídas por uma string de substituição:
REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
Sim REPLACE REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
TRIM Remova carateres à esquerda ou à direita (ou ambos) de uma string:
TRIM(both '-' FROM '-MySQL-') = MySQL TRIM(' MySQL ') = MySQL
Sim TRIM TRIM(both '-' FROM '-MySQL-') = MySQL TRIM(' MySQL ') = MySQL
LTRIM/RTRIM Remove do lado esquerdo ou direito de uma string todos os carateres que aparecem na pesquisa:
LTRIM(' MySQL', ' ') = MySQL
Parcialmente LTRIM or RTRIM As funções Oracle LTRIM e RTRIM usam um segundo parâmetro que especifica os carateres iniciais ou finais a remover da string. As funções do Cloud SQL para MySQL apenas removem espaços em branco iniciais e finais da string especificada:
LTRIM(' MySQL') = MySQL
ASCII Aceita um único caráter e devolve o respetivo código ASCII numérico:
ASCII('A') = 65
Sim ASCII ASCII('A') = 65
CHR Devolve o valor do código ASCII, que é um valor numérico de 0 a 225, para um caráter:
CHR(65) = A
Requer um nome de função diferente CHAR O Cloud SQL para MySQL usa a função CHAR para a mesma funcionalidade, pelo que tem de alterar o nome da função:
CHAR(65) = A
LENGTH Devolve o comprimento de uma determinada string:
LENGTH('MySQL') = 5
Sim LENGTH LENGTH('MySQL') = 5
REGEXP_REPLACE Pesquisa uma string para um padrão de expressão regular:
REGEXP_REPLACE('John', '[hn].', 'e') = Joe
Não N/A Suportado a partir da versão 8 do MySQL. Como solução alternativa, use a função REPLACE, se possível, ou mova a lógica para a camada de aplicação.
REGEXP_SUBSTR Expande a funcionalidade da função SUBSTR pesquisando uma string para um padrão de expressão regular:
REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?') = https://console.cloud.google.com/
Não N/A Suportado a partir da versão 8 do MySQL. Como solução alternativa, use a função SUBSTR, se possível, ou mova a lógica para a camada de aplicação
REGEXP_COUNT Devolve o número de vezes que um padrão ocorre numa string de origem Não N/A Não está disponível nenhuma função equivalente para o Cloud SQL para MySQL. Mova esta lógica para a camada de aplicação.
REGEXP_INSTR Pesquise uma posição (índice) de string para um padrão de expressão regular Não N/A Suportado a partir da versão 8 do MySQL. Se estiver numa versão mais antiga, mova esta lógica para a camada da aplicação.
REVERSE Devolve a string invertida para uma determinada string:
REVERSE('MySQL') = LQSyM
Sim REVERSE REVERSE('MySQL') = LQSyM

A tabela seguinte descreve onde as funções numéricas do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade, e onde se recomenda uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
ABS Devolve o valor absoluto de um determinado número:
ABS(-4.6) = 4.6
Sim ABS ABS(-4.6) = 4.6
CEIL Devolve o menor número inteiro que é maior ou igual ao número indicado:
CEIL(21.4) = 22
Sim CEIL CEIL(21.4) = 22
FLOOR Devolve o maior número inteiro igual ou inferior ao número fornecido:
FLOOR(-23.7) = -24
Sim FLOOR FLOOR(-23.7) = -24
MOD Devolve o resto da divisão de m por n:
MOD(10, 3) = 1
Sim MOD MOD(10, 3) = 1
ROUND Devolve n arredondado para o número inteiro de casas à direita da vírgula decimal:
ROUND(1.39, 1) = 1.4
Sim ROUND ROUND(1.39, 1) = 1.4
TRUNC(number) Devolve n1 truncado para n2 casas decimais. O segundo parâmetro é opcional.
TRUNC(99.999) = 99 TRUNC(99.999, 0) = 99
Requer um nome de função diferente TRUNCATE(number) A função do Cloud SQL para MySQL tem um nome diferente e o segundo parâmetro é obrigatório.
TRUNCATE(99.999, 0) = 99

A tabela seguinte descreve onde as funções do Oracle e do Cloud SQL para MySQL datetime são equivalentes por nome e funcionalidade, e onde se recomenda uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
SYSDATE Devolve a data e a hora atuais definidas para o sistema operativo no qual o servidor de base de dados reside:
SELECT SYSDATE FROM DUAL; = 31-JUL-2019
Sim SYSDATE()

O Cloud SQL para MySQL SYSDATE()tem de incluir parênteses e devolve, por predefinição, um formato datetime diferente do da função SYSDATE Oracle:

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

Pode alterar o formato datetime ao nível da sessão

SYSTIMESTAMP Devolve a data do sistema, incluindo frações de segundos e o fuso horário:
SELECT SYSTIMESTAMP FROM DUAL = 01-JAN-19 07.37.11.622187000 AM +00:00
Requer um nome de função diferente CURRENT_ TIMESTAMP A função Cloud SQL para MySQL devolve um formato datetime diferente por predefinição. Para reformatar a saída, use a função DATE_FORMAT().
SELECT CURRENT_TIMESTAMP FROM DUAL; = 2019-01-31 06:55:07
LOCAL_ TIMESTAMP Devolve a data e a hora atuais como um tipo TIMESTAMP:
SELECT LOCALTIMESTAMP FROM DUAL = 01-JAN-19 10.01.10.123456 PM
Devolve um formato datetime diferente LOCAL_ TIMESTAMP A função Cloud SQL para MySQL devolve um formato diferente do formato predefinido para o Oracle.datetime Para reformatar a saída, use a função DATE_FORMAT().
SELECT LOCAL_TIMESTAMP FROM DUAL = 2019-01-01 10:01:01.0
CURRENT_DATE Devolve a data atual:
SELECT CURRENT_DATE FROM DUAL = 31-JAN-19
Devolve um formato datetime diferente CURRENT_ DATE A função do Cloud SQL para MySQL devolve um formato datetime diferente. Para reformatar a saída, use a função DATE_FORMAT().
SELECT CURRENT_DATE FROM DUAL = 2019-01-31
CURRENT_ TIMESTAMP Devolve a data e a hora atuais:
SELECT CURRENT_TIMESTAMP FROM DUAL = 31-JAN-19 06.54.35.543146 AM +00:00
Devolve um formato datetime diferente CURRENT_ TIMESTAMP A função do Cloud SQL para MySQL devolve um formato datetime diferente. Para reformatar a saída, use a função DATE_FORMAT().
SELECT CURRENT_TIMESTAMP FROM DUAL = 2019-01-31 06:55:07
ADD_MONTHS Devolve a data mais o número inteiro de meses:
ADD_MONTHS(SYSDATE, 1) = 31-JAN-19
Requer um nome de função diferente ADDDATE A função do Cloud SQL para MySQL devolve um formato datetime diferente. Para reformatar a saída, use a função DATE_FORMAT().
ADDDATE(SYSDATE(), 1) = 2019-08-01 06:42:49.0
EXTRACT (parte da data) Devolve o valor de um campo datetime com base numa expressão de intervalo:
EXTRACT(YEAR FROM DATE '2019-01-31') = 2019
Sim EXTRACT (parte da data) EXTRACT(YEAR FROM DATE '2019-01-31') = 2019
LAST_DAY Devolve o último dia do mês para uma determinada data:
LAST_DAY('01-JAN-2019') = 31-JAN-19
Parcialmente LAST_DAY A função Cloud SQL para MySQL devolve um formato datetime diferente do formato predefinido para o Oracle. Para reformatar a saída, use a função DATE_FORMAT().
LAST_DAY('2019-01-01') = 2019-01-31
MONTH_ BETWEEN Devolve o número de meses entre as datas indicadas date1 e date2:
MONTHS_BETWEEN( SYSDATE, SYSDATE-60) = 1.96
Parcialmente PERIOD_DIFF A função PERIOD_DIFF do Cloud SQL para MySQL devolve a diferença em meses como um número inteiro entre dois períodos (formatados como YYMM ou YYYYMM):
PERIOD_DIFF( '201903', '201901') = 2
TO_CHAR (Datetime) Converte um número, um tipo datetime ou um tipo de data/hora num tipo de string
TO_CHAR( SYSDATE,'DD-MM-YYYY HH24:MI:SS') = 01-01-2019 10:01:01
Requer um nome de função diferente DATE_FORMAT A função DATE_FORMAT do Cloud SQL para MySQL
formata um valor de data de acordo com uma string de formato: DATE_FORMAT( SYSDATE(),'%d-%m-%Y %H:%i:%s') 01-01-2019 10:01:01

A tabela seguinte descreve onde as funções de codificação e descodificação do Oracle e do Cloud SQL for MySQL são equivalentes por nome e funcionalidade, e onde se recomenda uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
DECODE Compara a expressão com cada valor de pesquisa um a um através da funcionalidade de uma declaração IF-THEN-ELSE Não CASE Use a declaração CASE do Cloud SQL para MySQL para uma funcionalidade semelhante
DUMP Devolve um valor VARCHAR2 que contém o código do tipo de dados, o comprimento em bytes e a representação interna da expressão Não N/A Não suportado
ORA_HASH Calcula um valor hash para uma determinada expressão Não MD5 or SHA Use a função MD5 para somas de verificação de 128 bits ou a função SHA para somas de verificação de 160 bits

A tabela seguinte descreve onde as funções de conversão do Oracle e do Cloud SQL for MySQL são equivalentes por nome e funcionalidade, e onde se recomenda uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
CAST Converte um tipo de dados incorporado ou um valor de tipo de coleção noutro tipo de dados incorporado ou valor de tipo de coleção:
CAST('1' as int) + 1 = 2
Parcialmente CAST Ajuste consoante seja necessária uma conversão explícita ou implícita:
CAST('1' AS SIGNED) + 1 = 2
CONVERT Converte uma string de carateres de um conjunto de carateres para outro:
CONVERT ( 'Ä Ê Í Õ Ø A B C D E ', 'US7ASCII', 'WE8ISO8859P1') = ?? ?? ?? A B C
Parcialmente CONVERT A função CONVERT do Cloud SQL para MySQL requer alguns ajustes à sintaxe e aos parâmetros:
CONVERT( 'Ä Ê Í A B C ' USING utf8) = Ä Ê Í A B C
TO_CHAR (string/numérico) A função converte um número ou uma data numa string:
TO_CHAR(22.73,'$99.9') = $22.7
Não FORMAT A função FORMAT do Cloud SQL para MySQL converte um número num formato como #,###,###.##, arredondando-o para uma casa decimal e, em seguida, devolvendo o resultado como uma string:
CONCAT('$', FORMAT(22.73, 1)) = $22.7
TO_DATE A função TO_DATE do Oracle converte uma string numa data com base num formato datetimecode:
TO_DATE( '2019/01/01', 'yyyy-mm-dd') = 01-JAN-2019
Requer um nome de função diferente STR_TO_DATE A função Cloud SQL para MySQL STR_TO_DATE recebe uma string e devolve uma data com base num formato datetime:
STR_TO_DATE( '2019/01/01', '%Y/%m/%d') = 2019-01-01
TO_NUMBER Converte a expressão num valor de um tipo de dados NUMBER:
TO_NUMBER('01234') = 1234
Requer um nome de função diferente CAST Use a função CAST do Cloud SQL para MySQL para devolver o mesmo resultado que a função TO_NUMBER do Oracle:
CAST('01234' as SIGNED) = 1234

A tabela seguinte descreve onde as funções condicionais do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade, e onde se recomenda uma conversão.SELECT

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
CASE A declaração CASE escolhe a partir de uma sequência de condições e executa uma declaração correspondente com a seguinte sintaxe:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END
Sim CASE Além da função CASE, o Cloud SQL para MySQL suporta a utilização de IF/ELSE processamento condicional na declaração SELECT:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

A tabela seguinte descreve onde as funções nulas do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade, e onde se recomenda uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
COALESCE Devolve a primeira expressão não nula na lista de expressões:
COALESCE( null, '1', 'a') = a
Sim COALESCE COALESCE( null, '1', 'a') = 1
NULLIF Faz uma comparação entre expression1 e expression2. Se forem iguais, a função devolve null. Se não forem iguais, a função devolve expression1:
NULLIF('1', '2') = a
Sim NULLIF NULLIF('1', '2') = a
NVL Substitui um valor null por uma string nos resultados de uma consulta:
NVL(null, 'a') = a
Não IFNULL IFNULL(null, 'a') = a
NVL2 Determina o valor devolvido por uma consulta com base no facto de uma expressão ser nula ou não nula Não CASE A declaração CASE escolhe a partir de uma sequência de condições e executa uma declaração correspondente:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

A tabela seguinte descreve onde as funções de ambiente e identificador do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade e onde é recomendada uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
SYS_GUID Gera e devolve um identificador único global (valor RAW) composto por 16 bytes:
SELECT SYS_GUID() FROM DUAL = 8EFA4A31468B4C6DE05011AC0200009E
Não REPLACE e UUID Como solução alternativa, use as funções REPLACE e UUID para simular a função SYS_GUID:
REPLACE( UUID(), '-', '')
UID Devolve um número inteiro que identifica exclusivamente o utilizador da sessão (o utilizador com sessão iniciada):
SELECT UID FROM DUAL = 43
Não N/A N/A
USER Devolve o nome de utilizador do utilizador que está ligado à sessão atual:
SELECT USER FROM DUAL = username
Sim USER + INSTR + SUBSTR A função USER do Cloud SQL para MySQL devolve o nome de utilizador e o nome do anfitrião (root@IP_ADDRESS) para a ligação. Para obter apenas o nome de utilizador, use as funções de apoio adicionais:
SELECT SUBSTR(USER(), 1, INSTR(USER(), '@') -1) FROM DUAL = root
USERENV Devolve informações sobre a sessão atual do Oracle, como o idioma da sessão:
SELECT USERENV('LANGUAGE') FROM DUAL = ENGLISH_AMERICA. AL32UTF8
Não SHOW SESSION VARIABLES A declaração SHOW SESSION VARIABLES do Cloud SQL para MySQL devolve as definições da sessão atual:
SHOW SESSION VARIABLES LIKE '%collation%'; = utf8_general_ci
ROWID O Oracle atribui a cada linha de uma tabela um ROWID exclusivo para identificar a linha na tabela. O ROWID é a morada da linha que contém o número do objeto de dados, o bloco de dados da linha, a posição da linha e o ficheiro de dados. Parcialmente N/A O ROW_NUMBER() está disponível a partir do MySQL 8.0. Se estiver a usar uma versão anterior, emule a mesma funcionalidade usando uma variável de sessão @row_number.
ROWNUM Devolve um número que representa a ordem pela qual uma linha é devolvida por uma tabela Oracle Parcialmente N/A O ROW_NUMBER() está disponível a partir do MySQL 8.0. Se estiver a usar uma versão anterior, emule a mesma funcionalidade usando uma variável de sessão @row_number.

A tabela seguinte descreve onde as funções de agregação (grupo) do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade, e onde é recomendada uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
AVG Devolve o valor médio de uma coluna ou expressão Sim AVG Equivalente a Oracle
COUNT Devolve o número de linhas devolvidas por uma consulta Sim COUNT Equivalente a Oracle
COUNT (DISTINCT) Devolve o número de valores únicos na coluna ou expressão Sim COUNT (DISTINCT) Equivalente a Oracle
MAX Devolve o valor máximo de uma coluna ou expressão Sim MAX Equivalente a Oracle
MIN Devolve o valor mínimo de uma coluna ou expressão Sim MIN Equivalente a Oracle
SUM Devolve a soma de um valor de uma coluna ou expressão Sim SUM Equivalente a Oracle
LISTAGG Ordena os dados em cada grupo especificado na cláusula ORDER BY e concatena os valores da coluna de métricas:
SELECT LISTAGG( DEPARTMENT_NAME, ', ') WITHIN GROUP (ORDER BY DEPARTMENT_NAME) DEPT FROM DEPARTMENTS; -- Single line results = Accounting, Administration, Benefits, Construction
Requer um nome de função e uma sintaxe diferentes GROUP_ CONCAT Use a função GROUP_CONCAT do 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

A tabela seguinte descreve onde a função do Oracle e do Cloud SQL para MySQL FETCH é equivalente por nome e funcionalidade.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL Implementação do Cloud SQL para MySQL
FETCH Obtém um número especificado de linhas do conjunto de resultados de uma consulta de várias linhas:
SELECT * FROM EMPLOYEES FETCH FIRST 10 ROWS ONLY;
Sim LIMIT Use a cláusula LIMIT do MySQL para obter linhas de uma consulta:
SELECT * FROM EMPLOYEES LIMIT 10;

Filtragem básica, operadores e subconsultas

A filtragem básica, as funções de operador e as subconsultas são relativamente fáceis de converter, com um esforço nominal necessário. A maior parte do esforço gira em torno da conversão de formatos de data, porque o Oracle e o Cloud SQL para MySQL usam formatos de data predefinidos diferentes:

  • A função SYSDATE do Oracle devolve este formato por predefinição: 01-AUG-19.
  • A função SYSDATE() do Cloud SQL para MySQL devolve este formato por predefinição: 2019-08-01 12:04:05.

Para definir formatos de data e hora, use as funções MySQL DATE_FORMAT ou STR_TO_DATE.

A tabela seguinte descreve onde a filtragem, os operadores e as funções de subconsulta básicas do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade, e onde é recomendada uma conversão.

Função Oracle Implementação da Oracle Equivalente do Cloud SQL para MySQL Função do Cloud SQL para MySQL
EXISTS/ NOT EXISTS Sim EXISTS/ NOT EXISTS SELECT * FROM DEPARTMENTS D WHERE EXISTS (SELECT 1 FROM EMPLOYEES E WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID);
IN/NOT IN Sim 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 Sim LIKE/NOT LIKE SELECT * FROM EMPLOYEES WHERE FIRST_NAME LIKE '_e_n%';
BETWEEN/ NOT BETWEEN Sim BETWEEN/ NOT BETWEEN SELECT * FROM EMPLOYEES WHERE EXTRACT(YEAR FROM HIRE_DATE) NOT BETWEEN 2001 and 2004;
AND/OR Sim AND/OR SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID IN(100, 101) AND (SALARY >= 1000 OR HIRE_DATE <= '2006-02-05');
SubQuery Sim SubQuery O Cloud SQL para MySQL suporta subconsultas na cláusula SELECT, na cláusula JOIN e para filtragem nas 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 Sim Operadores O Cloud SQL para MySQL suporta todos os operadores básicos:
> | >= | < | <= | = | <> | !=

Práticas recomendadas para consultas do Cloud SQL para MySQL

Para manter níveis de desempenho comparáveis entre o Cloud SQL para MySQL e o Oracle, pode ter de otimizar as suas consultas. Estas otimizações incluem alterar as estruturas de índice e ajustar o esquema da base de dados. Esta secção apresenta algumas diretrizes para ajudar a alcançar um desempenho de consultas comparável no Cloud SQL para MySQL.

Crie um índice agrupado

Quando usar o motor de armazenamento InnoDB, uma prática recomendada é definir uma tabela com uma chave primária, porque esta chave cria um índice agrupado nessa tabela. Além de melhorar o desempenho das consultas, esta abordagem também lhe permite criar índices secundários adicionais. No entanto, deve evitar criar demasiados índices. Ter índices redundantes não melhora o desempenho e pode abrandar a execução de DML. Esta prática recomendada leva a uma segunda prática recomendada: monitorize regularmente os índices redundantes e, se tiver algum, remova-o da base de dados.

Use a seguinte consulta para identificar tabelas sem chaves principais, para que possa criar chaves principais para as mesmas:

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

Use a seguinte consulta para encontrar tabelas que não têm índices para que possa criar índices para as mesmas:

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

Use a seguinte consulta para verificar se existem índices redundantes para que possa remover as redundâncias:

mysql> SELECT * FROM sys.schema_redundant_indexes;

Ajuste os parâmetros de consulta

Para otimizar o desempenho das consultas, pode ter de ajustar os parâmetros da sessão. O Cloud SQL para MySQL tem um conjunto de flags que pode alterar para este fim, incluindo as seguintes flags:

  • Parâmetros relacionados com o InnoDB
  • Parâmetros SORT
  • Parâmetros JOIN
  • Parâmetros de processamento da cache

Monitorize consultas

As consultas de execução lenta podem fazer com que o sistema deixe de responder ou originar outros estrangulamentos, pelo que é importante monitorizar as consultas regularmente.

Existem várias formas de diagnosticar declarações SQL de execução lenta:

  • Use o painel de controlo do Cloud SQL para MySQL para ver estatísticas em tempo real e do histórico sobre consultas de execução lenta.
  • Use o Cloud Monitoring para monitorizar o registo de consultas lentas do Cloud SQL para MySQL.
  • Use a vista statement_analysis do Cloud SQL para MySQL para ver as estatísticas de tempo de execução sobre uma declaração SQL:

    mysql> SELECT * FROM sys.statement_analysis;
    

Analise consultas do Cloud SQL para MySQL

O otimizador de consultas no Cloud SQL para MySQL gera um plano de execução para declarações SELECT, INSERT, UPDATE e DELETE. Estes planos são úteis quando ajusta uma consulta de execução lenta. Há alguns aspetos a considerar:

  • Os planos de execução não são objetos de base de dados que precisam de ser migrados; em vez disso, são uma ferramenta para analisar as diferenças de desempenho entre o Oracle e o Cloud SQL para MySQL que executam a mesma declaração em conjuntos de dados idênticos.
  • O Cloud SQL para MySQL não suporta a mesma sintaxe, funcionalidade nem resultado do plano de execução que o Oracle.

Segue-se um plano de exemplo para ilustrar as diferenças entre um plano de execução do Oracle e um plano de execução do 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  |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+

Otimize os procedimentos armazenados e os acionadores

Ao contrário do Oracle, os procedimentos armazenados e as funções do Cloud SQL para MySQL são analisados em cada execução. Uma ferramenta útil para testes de referência do desempenho de funções e procedimentos armazenados é a utilidade MySQL BENCHMARK(). Esta ferramenta usa dois parâmetros, uma contagem de iterações e uma expressão, e estima o tempo de execução da expressão fornecida (por exemplo, procedimento armazenado, função e declaração SELECT). A saída representa o tempo de execução total aproximado em todas as iterações.

Segue-se um exemplo para ilustrar a utilidade 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

Se notar uma regressão do desempenho durante a conversão, use o comando MySQL EXPLAIN para identificar possíveis fatores que contribuem para a regressão. Uma solução comum para o desempenho lento é alterar a estrutura de um índice de tabela para se adequar ao otimizador do MySQL. Outra prática comum é otimizar um código PL/SQL convertido reduzindo a obtenção de dados desnecessários ou usando tabelas temporárias no código MySQL processual.

O que se segue?

  • Explore mais sobre as contas de utilizador do MySQL.
  • Explore arquiteturas de referência, diagramas e práticas recomendadas sobre o Google Cloud. Consulte o nosso Centro de arquitetura na nuvem.