Como converter e otimizar consultas do Oracle Database para o Cloud SQL para MySQL

Neste documento, discutimos as diferenças básicas de consulta entre o Oracle® e o Cloud SQL para MySQL e como os recursos no Oracle são mapeados para os recursos no Cloud SQL para MySQL. Também descrevemos considerações de desempenho do Cloud SQL para MySQL e maneiras de analisar e otimizar o desempenho da consulta no Google Cloud. Neste documento, abordamos técnicas para otimizar procedimentos e acionadores armazenados para o Cloud SQL para MySQL, mas não abordamos como traduzir o código PL/SQL para procedimentos e funções armazenados do MySQL.

Ao converter consultas do banco de dados Oracle para o Cloud SQL para MySQL, há algumas diferenças de dialeto SQL a serem consideradas. Há também várias funções integradas que são diferentes ou incompatíveis entre as duas plataformas de banco de dados.

Diferenças básicas de consulta

Ainda que o Oracle e o Cloud SQL para MySQL sejam compatíveis com ANSI SQL, há várias diferenças fundamentais ao consultar dados, principalmente em relação ao uso de funções do sistema.

A tabela a seguir destaca as diferenças na sintaxe SELECT e FROM para Oracle e Cloud SQL para MySQL.

Nome do recurso da Oracle Implementação da Oracle Suporte do Cloud SQL para MySQL Equivalente do Cloud SQL para MySQL
Sintaxe básica do SQL para recuperaçã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 de coluna SELECT COL1 AS C1 Sim SELECT COL1 AS C1
ou
SELECT COL1 C1
Diferenciação entre maiúsculas e minúsculas no nome da tabela Nenhuma diferenciação de maiúsculas e minúsculas (por exemplo, o nome da tabela pode ser orders e ORDERS) Não Diferencia maiúsculas de minúsculas de acordo com o nome da tabela definido (por exemplo, o nome da tabela pode ser apenas orders ou ORDERS)

Visualizações in-line

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

O exemplo a seguir descreve um exemplo de conversão do Oracle 11g/12c para o Cloud SQL para MySQL para uma visualização in-line.

Uma visualização in-line no Oracle 11g/12c:

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

Uma visualização de trabalho 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;

Mesclagens

Os tipos mesclagens da Oracle são compatíveis com o Cloud SQL para MySQL, exceto o FULL JOIN. As mesclagens do Cloud SQL para MySQL são compatíveis com o uso de sintaxe alternativa, como a cláusula USING, a cláusula WHERE em vez da ON e a SUBQUERY na instrução JOIN.

A tabela a seguir mostra um exemplo de conversão JOIN.

Tipo JOIN da Oracle Suporte do Cloud SQL para MySQL Sintaxe JOIN do Cloud SQL para MySQL
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;

O Cloud SQL para MySQL é compatível com as funções UNION e UNION ALL, mas não com as funções INTERSECT e MINUS da Oracle:

  • UNION anexa os conjuntos de resultados de duas instruções SELECT depois de eliminar registros duplicados.
  • UNION ALL anexa os conjuntos de resultados de duas instruções SELECT sem eliminar registros duplicados.
  • INTERSECT retorna a interseção de duas instruções SELECT, somente se houver um registro nos conjuntos de resultados de ambas as consultas.
  • MINUS compara duas ou mais instruções SELECT, retornando apenas linhas distintas da primeira consulta que não são retornadas pela segunda consulta.

A tabela a seguir 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 fornece 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 vias do Oracle (por nome e funcionalidade, ou com um nome diferente, mas com funcionalidade semelhante). Mesmo que algumas funções do Cloud SQL para MySQL possam ter nomes idênticos às vias da Oracle, elas também podem exibir diferentes funcionalidades.

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

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 Retorna 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 Retorna a string, com todas as letras em minúsculas ou em maiúsculas:
LOWER('SQL') = sql
Sim LOWER ou UPPER LOWER('SQL') = sql
LPAD/RPAD Retorna expression1, à esquerda ou à direita preenchidos com n caracteres com a sequência de caracteres em expression2:
LPAD('A',3,'*') = **A
Sim LPAD ou RPAD LPAD('A',3,'*') = **A
SUBSTR Retorna 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 Retorna a posição (índice) de uma string de uma determinada string:
INSTR('MySQL', 'y') = 2
Sim INSTR INSTR('MySQL', 'y') = 2
REPLACE Retorna uma string com cada ocorrência de uma string de pesquisa substituída por uma string de substituição:
REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
Sim REPLACE REPLACE('ORADB', 'ORA', 'MySQL') = MySQLDB
TRIM Cortar caracteres iniciais ou finais (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 caracteres que aparecem na pesquisa:
LTRIM(' MySQL', ' ') = MySQL
Parcialmente LTRIM or RTRIM As funções LTRIM e RTRIM da Oracle usam um segundo parâmetro que especifica os caracteres iniciais ou finais a serem removidos da string. As funções do Cloud SQL para MySQL removem apenas os espaços em branco à esquerda e à direita da string especificada:
LTRIM(' MySQL') = MySQL
ASCII Usa um único caractere e retorna o código ASCII numérico:
ASCII('A') = 65
Sim ASCII ASCII('A') = 65
CHR Retorna o valor do código ASCII, que é um valor numérico de 0 a 255, para um caractere:
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. Portanto, você precisa alterar o nome da função:
CHAR(65) = A
LENGTH Retorna o comprimento de uma determinada string:
LENGTH('MySQL') = 5
Sim LENGTH LENGTH('MySQL') = 5
REGEXP_REPLACE Pesquisa um padrão de expressão regular em uma string:
REGEXP_REPLACE('John', '[hn].', 'e') = Joe
Não N/A Compatível 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 do aplicativo.
REGEXP_SUBSTR Estende a funcionalidade da função SUBSTR pesquisando um padrão de expressão regular em uma string:
REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?') = https://console.cloud.google.com/
Não N/A Compatível 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 do aplicativo
REGEXP_COUNT Retorna o número de vezes que um padrão ocorre em uma string de origem Não N/A Nenhuma função equivalente disponível para o Cloud SQL para MySQL. Mova essa lógica para a camada do aplicativo.
REGEXP_INSTR Pesquisar uma posição de string (índice) para um padrão de expressão regular Não N/A Compatível a partir da versão 8 do MySQL. Se estiver em uma versão mais antiga, mova essa lógica para a camada do aplicativo.
REVERSE Retorna a string invertida de uma determinada string:
REVERSE('MySQL') = LQSyM
Sim REVERSE REVERSE('MySQL') = LQSyM

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

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 Retorna o valor absoluto de um determinado número:
ABS(-4.6) = 4.6
Sim ABS ABS(-4.6) = 4.6
CEIL Retorna o menor número inteiro maior ou igual ao número fornecido:
CEIL(21.4) = 22
Sim CEIL CEIL(21.4) = 22
FLOOR Retorna o maior número inteiro igual ou menor que o número fornecido:
FLOOR(-23.7) = -24
Sim FLOOR FLOOR(-23.7) = -24
MOD Retorna o restante de m dividido por n:
MOD(10, 3) = 1
Sim MOD MOD(10, 3) = 1
ROUND Retorna n arredondado para casas inteiras à direita do ponto decimal:
ROUND(1.39, 1) = 1.4
Sim ROUND ROUND(1.39, 1) = 1.4
TRUNC(número) Retorna 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(número) 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 a seguir descreve onde as funções datetime do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade e onde uma conversão é recomendada.

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 Retorna a data e a hora atuais definidas para o sistema operacional em que o servidor de banco de dados reside:
SELECT SYSDATE FROM DUAL; = 31-JUL-2019
Sim SYSDATE()

O Cloud SQL para MySQL SYSDATE() precisa incluir parênteses e retornar por padrão um formato datetime diferente da função SYSDATE da Oracle:

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

É possível alterar o formato datetime no nível da sessão

SYSTIMESTAMP Retorna a data do sistema, incluindo segundos fracionários e 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 do Cloud SQL para MySQL retorna um formato datetime diferente por padrã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 Retorna a data e a hora atuais como um tipo TIMESTAMP:
SELECT LOCALTIMESTAMP FROM DUAL = 01-JAN-19 10.01.10.123456 PM
Retorna um formato datetime diferente LOCAL_ TIMESTAMP A função do Cloud SQL para MySQL retorna um formato datetime diferente do formato padrão do Oracle. 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 Retorna a data atual:
SELECT CURRENT_DATE FROM DUAL = 31-JAN-19
Retorna um formato datetime diferente CURRENT_ DATE A função do Cloud SQL para MySQL retorna 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 Retorna a data e a hora atuais:
SELECT CURRENT_TIMESTAMP FROM DUAL = 31-JAN-19 06.54.35.543146 AM +00:00
Retorna um formato datetime diferente CURRENT_ TIMESTAMP A função do Cloud SQL para MySQL retorna 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 Retorna a data mais os meses inteiros:
ADD_MONTHS(SYSDATE, 1) = 31-JAN-19
Requer um nome de função diferente ADDDATE A função do Cloud SQL para MySQL retorna 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) Retorna o valor de um campo datetime com base em uma 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 Retorna o último dia do mês para uma determinada data:
LAST_DAY('01-JAN-2019') = 31-JAN-19
Parcialmente LAST_DAY A função do Cloud SQL para MySQL retorna um formato datetime diferente do formato padrão para Oracle. Para reformatar a saída, use a função DATE_FORMAT().
LAST_DAY('2019-01-01') = 2019-01-31
MONTH_ BETWEEN Retorna o número de meses entre as datas especificadas date1 e date2:
MONTHS_BETWEEN( SYSDATE, SYSDATE-60) = 1.96
Parcialmente PERIOD_DIFF A função PERIOD_DIFF do Cloud SQL para MySQL retorna a diferença em meses como um número inteiro entre dois pontos (formatados como YYMM ou YYYYMM):
PERIOD_DIFF( '201903', '201901') = 2
TO_CHAR (Datetime) Converte um número, datetime ou tipo de carimbo de data/hora em um 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 a seguir descreve onde as funções de codificação e decodificação do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade e onde uma conversão é recomendada.

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 por um, usando a funcionalidade de uma instrução IF-THEN-ELSE Não CASE Usar a instrução CASE do Cloud SQL para MySQL para funcionalidade semelhante
DUMP Retorna um valor VARCHAR2 contendo o código do tipo de dados, o comprimento em bytes e a representação interna da expressão Não N/A Incompatível
ORA_HASH Calcula um valor de 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 SHA para somas de verificação de 160 bits

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

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 integrado ou um valor digitado por conjunto em outro tipo de dados integrado ou valor digitado por conjunto:
CAST('1' as int) + 1 = 2
Parcialmente CAST Ajuste se uma conversão explícita ou implícita for necessária:
CAST('1' AS SIGNED) + 1 = 2
CONVERT Converte uma string de caracteres de um conjunto de caracteres em 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 na sintaxe e nos 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 em uma 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 em um formato como #,###,###.##, arredondando-o para uma casa decimal e retornando o resultado como uma string:
CONCAT('$', FORMAT(22.73, 1)) = $22.7
TO_DATE A função TO_DATE da Oracle converte uma string em uma data com base em um 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 STR_TO_DATE do Cloud SQL para MySQL usa uma string e retorna uma data com base em um formato datetime:
STR_TO_DATE( '2019/01/01', '%Y/%m/%d') = 2019-01-01
TO_NUMBER Converte a expressão em um 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 retornar o mesmo resultado que a função TO_NUMBER da Oracle:
CAST('01234' as SIGNED) = 1234

A tabela a seguir descreve onde as funções SELECT condicionais do Oracle e do Cloud SQL para MySQL são equivalentes por nome e funcionalidade e onde uma conversão é recomendada.

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 instrução CASE escolhe uma sequência de condições e executa uma instruçã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 é compatível com o uso condicional IF/ELSE na instrução SELECT:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

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

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 Retorna 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 Executa uma comparação entre expression1 e expression2. Se forem iguais, a função retornará null. Se eles não forem iguais, a função retornará 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 retornado por uma consulta com base no fato de uma expressão ser nula ou não Não CASE A instrução CASE escolhe uma sequência de condições e executa uma instrução correspondente:
CASE WHEN condition THEN result [WHEN ...] [ELSE result] END

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

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 retorna um identificador globalmente exclusivo (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 Retorna um número inteiro que identifica exclusivamente o usuário da sessão (o usuário conectado):
SELECT UID FROM DUAL = 43
Não N/A N/A
USER Retorna o nome de usuário do usuário conectado à sessão atual:
SELECT USER FROM DUAL = username
Sim USER + INSTR + SUBSTR A função USER do Cloud SQL para MySQL retorna o nome de usuário e o nome do host (root@IP_ADDRESS) da conexão. Para recuperar apenas o nome de usuário, use as funções de suporte adicionais:
SELECT SUBSTR(USER(), 1, INSTR(USER(), '@') -1) FROM DUAL = root
USERENV Retorna informações sobre a sessão atual da Oracle, como o idioma da sessão:
SELECT USERENV('LANGUAGE') FROM DUAL = ENGLISH_AMERICA. AL32UTF8
Não SHOW SESSION VARIABLES A instrução SHOW SESSION VARIABLES do Cloud SQL para MySQL retorna as configuraçõ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 é o endereço 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 arquivo de dados. Parcialmente N/A ROW_NUMBER() está disponível a partir do MySQL 8.0. Se você estiver usando uma versão anterior, emule a mesma funcionalidade usando uma variável de sessão @row_number.
ROWNUM Retorna um número que representa a ordem em que uma linha é retornada por uma tabela da Oracle Parcialmente N/A ROW_NUMBER() está disponível a partir do MySQL 8.0. Se você estiver usando uma versão anterior, emule a mesma funcionalidade usando uma variável de sessão @row_number.

A tabela a seguir 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 uma conversão é recomendada.

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

A tabela a seguir descreve onde a função FETCH do Oracle e do Cloud SQL para MySQL é 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 Recupera 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 (em inglês) do MySQL para recuperar linhas de uma consulta:
SELECT * FROM EMPLOYEES LIMIT 10;

Filtragem básica, operadores e subconsultas

A filtragem básica, as funções do operador e as subconsultas são relativamente simples de converter, com esforço mínimo necessário. A maior parte do esforço envolve a conversão de formatos de data porque o Oracle e o Cloud SQL para MySQL usam diferentes formatos de data padrão:

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

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

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

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 é compatível com 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 é compatível com 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, talvez seja necessário otimizar suas consultas. Essas otimizações incluem alterar as estruturas de índice e ajustar o esquema do banco de dados. Nesta seção, fornecemos algumas diretrizes para ajudar você a alcançar um desempenho de consulta comparável no Cloud SQL para MySQL.

Criar um índice em cluster

Ao usar o mecanismo de armazenamento InnoDB (em inglês), uma prática recomendada é definir uma tabela com uma chave primária, porque ela cria um índice em cluster nessa tabela. Além de melhorar o desempenho da consulta, essa abordagem também permite criar índices secundários adicionais. No entanto, você quer evitar a criação de muitos índices. Ter índices redundantes não melhora o desempenho e pode atrasar a execução do DML (em inglês). Essa prática recomendada leva a uma segunda prática recomendada: monitore regularmente os índices redundantes e, se houver algum, remova-os do banco de dados.

Use a consulta a seguir para identificar tabelas sem chaves primárias para criar chaves primárias para elas:

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 consulta a seguir para encontrar tabelas que não têm índices para que você possa criar índices para elas:

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 consulta a seguir para verificar índices redundantes e remover os redundantes:

mysql> SELECT * FROM sys.schema_redundant_indexes;

Ajustar parâmetros de consulta

Para ajustar o desempenho da consulta, talvez seja necessário ajustar os parâmetros da sessão. O Cloud SQL para MySQL tem um conjunto de sinalizações que podem ser alteradas para essa finalidade, incluindo as seguintes sinalizações:

  • Parâmetros relacionados ao InnoDB
  • SORT parâmetros
  • JOIN parâmetros
  • Parâmetros de manipulação de cache

Monitorar consultas

Consultas com execução lenta podem fazer com que o sistema pare de responder ou levar a outros gargalos, por isso é importante monitorar regularmente as consultas.

Há várias maneiras de diagnosticar instruções SQL de execução lenta:

  • Use o painel do Cloud SQL para MySQL para ver insights históricos e em tempo real sobre consultas de execução lenta.
  • Use o Cloud Monitoring para monitorar o registro de consulta lenta do Cloud SQL para MySQL.
  • Use a visualização statement_analysis do Cloud SQL para MySQL para ver as estatísticas de tempo de execução sobre uma instrução SQL:

    mysql> SELECT * FROM sys.statement_analysis;
    

Analisar consultas do Cloud SQL para MySQL

O otimizador de consultas no Cloud SQL para MySQL gera um plano de execução para as instruções SELECT, INSERT, UPDATE e DELETE. Esses planos são úteis quando você ajusta uma consulta de execução lenta. Considere as seguintes informações:

  • Os planos de execução não são objetos de banco de dados que precisam ser migrados. Em vez disso, eles são uma ferramenta para analisar as diferenças de desempenho entre o Oracle e o Cloud SQL para MySQL executando a mesma instrução em conjuntos de dados idênticos.
  • O Cloud SQL para MySQL não é compatível com a mesma sintaxe, funcionalidade ou saída do plano de execução do Oracle.

Veja um exemplo de plano para ilustrar as diferenças entre um plano de execução da 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  |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+

Otimizar gatilhos e procedimentos armazenados

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

Veja a seguir um exemplo para ilustrar o utilitário 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 você notar uma regressão de desempenho durante a conversão, use o comando EXPLAIN do MySQL para identificar possíveis fatores que contribuem para a regressão. Uma solução comum para desempenho lento é alterar uma estrutura de índice de tabela para acomodar o otimizador do MySQL. Outra prática comum é otimizar um código PL/SQL convertido reduzindo a recuperação de dados desnecessária ou usando tabelas temporárias no código processual do MySQL.

A seguir