本記事では、OceanBaseにおけるデータベースSELECT文の作成規範について説明します。
SELECT文では、具体的なフィールド名を指定することを推奨し、"*"として書くことは禁止されています。
クエリアナライザーの解析コストが増加します。
フィールドの追加や削除が容易であり、ResultMap設定との不一致を招きやすいです。
SELECTで不要な列を除外することを推奨します:SQL文のSELECT部分には必要な列のみを記述し、余分な列はデータベースによるテーブルへの再アクセス(データページに入り込んでリクエストされた特定の列を取得する)を引き起こし、より多くのI/Oを発生させる原因となります。
パーティションテーブルを使用するSQL文では、述語にパーティションキーを必ず含める必要があります。
count(*)の代わりにcount(列名)またはcount(定数)を使用することは推奨されません。count(*)はSQL92で定義された標準的な行数をカウントする構文であり、データベースやNULL値、非NULL値に関係なく適用されます。説明
count(*)はNULL値を持つ行をカウントしますが、count(列名)はこの列がNULL値の行をカウントしません。SELECT文では、必要な場合に限ってUNIONを使用し、UNION ALLを使用することを推奨します。また、UNION句の数は5個以下に制限します。
説明
UNIONは最後に自動的にソートを実行して重複を排除しますが、実際には異なるクエリ間に重複が存在することは通常ありません。
IN演算子の使用は推奨されません。INを含むサブクエリは、可能な限りJOINに書き換えることを推奨します。どうしても避けられない場合は、INの後ろの集合要素の数を慎重に評価し、100個以内に抑えることを推奨します。
読み取りロック
SELECT ... for update (with cs)の使用は推奨されません。トランザクションが大きい場合、高い同時実行性の下ではロック待機が発生し、業務に影響を与える可能性があります。等価クエリで異なる型の列を使用することは禁止されています。
説明
フィールドタイプがvarcharで、WHERE条件のフィールド内容がintの場合、暗黙的な型変換の問題が発生し、ソートインが機能せず、データベースをダウンさせる可能性があります。
ORDER BYクエリ文では、ORDER BYのフィールドは一意であるか、組み合わせて一意である必要があります(非一意フィールドのソートは、OceanBaseデータベースとMySQLの挙動が異なります)。
コア業務プロセスのSQLには、計算処理、複数テーブルの結合、テーブルイテレーション、CASE WHENなどの複雑なクエリを含めることは推奨されません。単一テーブルの単純なクエリに分割することを推奨します。
クエリ条件のフィルタリング性能が低い場合、緊急時の対応としてSQLにバインドされた実行計画を使用しますが、長期的な使用にはSQLロジックの修正を推奨します。過剰なHINTは、今後のアップグレードやメンテナンスに一定の影響を与える可能性があります。
DISTINCT、ORDER BY、GROUP BY句を含むクエリでは、中間結果セットは10000行以内に制限します。大規模な結果セット(中間結果セットが10000行を超える場合)のソートやグループ化は、プログラム側で実装することを推奨します。
パラレル数を設定する際、最適なパラレル数はそのテーブルのシャード数です。
WHERE条件では、テーブルフィールドに対する算術演算や関数計算を行うことは推奨されません。SQL文で変数に値を代入することは避けるべきです。特に分散処理において結果を変数に代入することは避けるべきです。
SQL文における条件フィールドのデータ型は一貫していなければならず、暗黙的な型変換を避ける必要があります。
SQL文の
SELECT投影フィールドでは、データベースの予約語を使用することは禁止されています。