2024年9月1日から、Database Autonomy Service (DAS) のSQLテンプレートアルゴリズムが最適化されました。
背景情報
DASは、低速クエリ用のSQLテンプレートアルゴリズムと、データ分析を実行するためのSQL監査を提供します。 DASは、SQL文を処理してSQLテンプレートアルゴリズムに基づいてSQLテンプレートを生成し、生成された同じ型のSQLテンプレートを集計して分析します。 現在のSQLテンプレートアルゴリズムは、切り捨てられたSQL文をうまく処理できません。 例えば、SQLステートメントが切り捨てられる位置の不確実性のために、拡張された数のSQLテンプレートが生成され得る。 この場合、生成されたテンプレートは集約するのに不便である。
有効日
2024年9月1日から、低速クエリとSQL監査用のSQLテンプレートアルゴリズムが最適化されました。
2024年9月1日以降、SQLテンプレートアルゴリズムの反復最適化に関する通知は届きません。 APIリクエストへの応答が優先されます。
有効範囲
ApsaraDB RDS for MySQL、ApsaraDB RDS for PostgreSQL、ApsaraDB RDS for SQL Server、ApsaraDB RDS for MariaDB、PolarDB for MySQLのデータベースエンジンが最適化をサポートしています。
Content
次の最適化が提供されます。
$$は、SQL文が処理されたときにApsaraDB RDS for PostgreSQLインスタンスの文字列定数区切り文字として使用でき、識別子が疑問符 (?) で誤って置き換えられるという問題が修正されました。たとえば、次の元のSQL文が使用されます。
UPDATE "study" SET "name" = 'xiaoming', "ext" = $${"math":90,"english":91}$$ where id=128;最適化の前に、次のSQLテンプレートが生成されます。
UPDATE ? SET ? = ?, ? = $${?:?,?:?}$$ where id=?;最適化後、次のSQLテンプレートが生成されます。
UPDATE "study" SET "name"=?,"ext"=? WHERE id=?;テーブル名と列名の数値サフィックスを置き換えて、テンプレートの数を減らすことができます。
たとえば、次の元のSQL文が使用されます。
select * from [school_3].[class].[student_25];最適化の前に、次のSQLテンプレートが生成されます。
select * from [school_3].[class].[student_25];最適化後、次のSQLテンプレートが生成されます。
SELECT * FROM [school_?].[class].[student_?];ApsaraDB RDS For SQL Serverインスタンスの場合、SQL文のプレフィックスは削除できます。 これにより、SQL文の種類を解析できます。
たとえば、次の元のSQL文が使用されます。
(@P0 nvarchar(4000))select id, name from student WHERE name = @P0;最適化の前に、次のSQLテンプレートが生成されます。
Generated SQL template: (@P0 nvarchar(?))select id, name from student WHERE name = @P0; Parsed type of the SQL statement: p0最適化後、次のSQLテンプレートが生成されます。
Generated SQL template: SELECT id,name FROM student WHERE name=?; Parsed type of the SQL statement: select構文に影響を与えることなく、スペースの数を最小限に抑え、元のSQL文のキーワードの大文字小文字を保持できます。 ケース変換は必要ありません。
たとえば、次の元のSQL文が使用されます。
select `name` from `student` where `id` = 1 and (`name` = 'xiaoming' or `class` = 2);最適化の前に、次のSQLテンプレートが生成されます。
SELECT `name` FROM `student` WHERE `id` = ? AND (`name` = ? OR `class` = ?)最適化後、次のSQLテンプレートが生成されます。
SELECT `name` FROM `student` WHERE `id`=? AND (`name`=? OR `class`=?);元のSQL文の括弧 (()) はすべて保持されます。
たとえば、次の元のSQL文が使用されます。
select `name` from `student` where `id` = 1 and (`name` = 'xiaoming');最適化の前に、次のSQLテンプレートが生成されます。
SELECT `name` FROM `student` WHERE `id` = ? AND `name` = ?最適化後、次のSQLテンプレートが生成されます。
SELECT `name` FROM `student` WHERE `id`=? AND (`name`=?);格式を囲む括弧 (()) は、「AS」に変換されなくなります。
たとえば、次の元のSQL文が使用されます。
select `name`, ( CASE WHEN score > 90 THEN 'A' END ) `grade` from `student`;最適化の前に、次のSQLテンプレートが生成されます。
SELECT `name` , CASE WHEN score > ? THEN ? END AS `grade` FROM `student`最適化後、次のSQLテンプレートが生成されます。
SELECT `name`,(CASE WHEN score>? THEN ? END)`grade` FROM `student`;番号記号 (#) の後のコンテンツは正しく解析できます。
たとえば、次の元のSQL文が使用されます。
select `name`, `#grade` from `student`;最適化の前に、次のSQLテンプレートが生成されます。
SELECT `name`, `最適化後、次のSQLテンプレートが生成されます。
SELECT `name`,`#grade` FROM `student`;DASが切り捨てられたSQL文を処理する場合、テンプレートの数を減らすために、ペアのない括弧内のすべてのコンテンツが破棄されます。
たとえば、次の元のSQL文が使用されます。
select `name`, `grade` from `student` where id = (select uid from最適化の前に、次のSQLテンプレートが生成されます。
select `name`, `grade` from `student` where id = (select uid from最適化後、次のSQLテンプレートが生成されます。
SELECT `name`,`grade` FROM `student` WHERE id=類似の式は、多数の類似の式によるテンプレートの拡張を防ぐためにマージされます。
たとえば、次の元のSQL文が使用されます。
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;最適化の前に、次のSQLテンプレートが生成されます。
SELECT CASE WHEN score >= ? THEN ? WHEN score >= ? THEN ? WHEN score >= ? THEN ? WHEN score >= ? THEN ? ELSE ? END AS grade FROM students最適化後、次のSQLテンプレートが生成されます。
スコアが >=?
SELECT CASE WHEN score>=? THEN ? ELSE ? END AS grade FROM students;
影響
最適化後にDescribeSlowLogsまたはDescribeSlowLogRecords操作を呼び出すと、SQLTextパラメーターに対応するSQLHashパラメーターの値が変更されます。
最適化後にGetFullRequestStatResultByInstanceIdまたはGetAsyncErrorRequestListByCode操作を呼び出すと、SqlIdパラメーターの値が変わります。