A partir de 1º de setembro de 2024, o algoritmo de modelo SQL no Database Autonomy Service (DAS) foi otimizado para melhorar a precisão e a agregação dos modelos.
Informações de contexto
O DAS usa o algoritmo de modelo SQL para processar instruções SQL em modelos, permitindo agregação e análise em cenários de consultas lentas e auditoria de SQL. O algoritmo anterior não lidava adequadamente com instruções SQL truncadas. Por exemplo, o truncamento em posições imprevisíveis podia causar a expansão de modelos e dificultar a agregação.
Data de vigência
A partir de 1º de setembro de 2024, o algoritmo de modelo SQL para consultas lentas e auditorias de SQL está otimizado.
Após 1º de setembro de 2024, não haverá mais envio de avisos sobre otimizações iterativas no algoritmo de modelo SQL. As respostas da API refletirão as alterações mais recentes.
Escopo de aplicação
A otimização aplica-se aos seguintes mecanismos de banco de dados: ApsaraDB RDS for MySQL, ApsaraDB RDS for PostgreSQL, ApsaraDB RDS for SQL Server, ApsaraDB RDS for MariaDB e PolarDB for MySQL.
Conteúdo
As seguintes otimizações foram implementadas:
-
O delimitador
$$agora é reconhecido como delimitador de constante de string no ApsaraDB RDS for PostgreSQL, e os identificadores não são mais substituídos incorretamente por pontos de interrogação (?).Por exemplo, considere a seguinte instrução SQL original:
UPDATE "study" SET "name" = 'xiaoming', "ext" = $${"math":90,"english":91}$$ where id=128;Antes da otimização, o seguinte modelo SQL era gerado:
UPDATE ? SET ? = ?, ? = $${?:?,?:?}$$ where id=?;Após a otimização, o seguinte modelo SQL é gerado:
UPDATE "study" SET "name"=?,"ext"=? WHERE id=?; -
Sufixos numéricos em nomes de tabelas e colunas são substituídos por espaços reservados para reduzir a quantidade de modelos.
Considere, por exemplo, esta instrução SQL original:
select * from [school_3].[class].[student_25];Antes da otimização, o resultado era este modelo SQL:
select * from [school_3].[class].[student_25];Com a otimização, o modelo SQL gerado passa a ser:
SELECT * FROM [school_?].[class].[student_?]; -
Em instâncias do ApsaraDB RDS for SQL Server, os prefixos das instruções SQL são removidos para aprimorar a análise do tipo de instrução.
Veja o exemplo abaixo com uma instrução SQL original:
(@P0 nvarchar(4000))select id, name from student WHERE name = @P0;O modelo SQL gerado anteriormente era:
Generated SQL template: (@P0 nvarchar(?))select id, name from student WHERE name = @P0; Parsed type of the SQL statement: p0Após a otimização, gera-se o seguinte modelo SQL:
Generated SQL template: SELECT id,name FROM student WHERE name=?; Parsed type of the SQL statement: select -
Espaços desnecessários são removidos e a caixa original das palavras-chave é preservada, sem afetar a sintaxe.
Tomando como base a instrução SQL original a seguir:
select `name` from `student` where `id` = 1 and (`name` = 'xiaoming' or `class` = 2);Antes da otimização, obtinha-se este modelo SQL:
SELECT `name` FROM `student` WHERE `id` = ? AND (`name` = ? OR `class` = ?)Depois da otimização, o modelo SQL resultante é:
SELECT `name` FROM `student` WHERE `id`=? AND (`name`=? OR `class`=?); -
Todos os parênteses (()) presentes na instrução SQL original são mantidos.
Observe a instrução SQL original abaixo:
select `name` from `student` where `id` = 1 and (`name` = 'xiaoming');O modelo SQL gerado antes da otimização era:
SELECT `name` FROM `student` WHERE `id` = ? AND `name` = ?Após a otimização, o sistema gera este modelo SQL:
SELECT `name` FROM `student` WHERE `id`=? AND (`name`=?); -
Os parênteses (()) que envolvem expressões CASE não são mais convertidos para "AS".
Utilizando a seguinte instrução SQL original como exemplo:
select `name`, ( CASE WHEN score > 90 THEN 'A' END ) `grade` from `student`;Antes da otimização, o modelo SQL produzido era:
SELECT `name` , CASE WHEN score > ? THEN ? END AS `grade` FROM `student`Com a otimização aplicada, o modelo SQL gerado é:
SELECT `name`,(CASE WHEN score>? THEN ? END)`grade` FROM `student`; -
O conteúdo após um sinal de número (#) agora é analisado corretamente.
Considere a instrução SQL original a seguir:
select `name`, `#grade` from `student`;O modelo SQL gerado anteriormente era:
SELECT `name`, `Após a otimização, o modelo SQL correto é gerado:
SELECT `name`,`#grade` FROM `student`; -
Para instruções SQL truncadas, o conteúdo dentro de parênteses não pareados é descartado para diminuir o número de modelos.
Veja o exemplo com esta instrução SQL original:
select `name`, `grade` from `student` where id = (select uid fromAntes da otimização, o modelo SQL resultante era:
select `name`, `grade` from `student` where id = (select uid fromApós a otimização, o modelo SQL gerado torna-se:
SELECT `name`,`grade` FROM `student` WHERE id= -
Expressões semelhantes são mescladas para evitar a expansão excessiva de modelos.
Analise a seguinte instrução SQL original:
SELECT CASE WHEN score >= 90 THEN 'A' WHEN score >= 80 THEN 'B' WHEN score >= 70 THEN 'C' WHEN score >= 60 THEN 'D' ELSE 'F' END AS grade FROM students;O modelo SQL gerado antes da otimização era:
SELECT CASE WHEN score >= ? THEN ? WHEN score >= ? THEN ? WHEN score >= ? THEN ? WHEN score >= ? THEN ? ELSE ? END AS grade FROM studentsApós a otimização, o modelo SQL simplificado é:
SELECT CASE WHEN score>=? THEN ? ELSE ? END AS grade FROM students;
Impacto
Após a otimização, o valor SQLHash para um determinado SQLText muda ao chamar a operação DescribeSlowLogs ou DescribeSlowLogRecords.
Além disso, o valor SqlId muda ao executar a operação GetFullRequestStatResultByInstanceId ou GetAsyncErrorRequestListByCode.