本記事では、OceanBaseにおけるデータベースSELECTステートメントの記述規範について説明します。
SELECTステートメントでは、具体的なフィールド名を指定することを推奨し、"*"で書くことは禁止されています。
クエリアナライザーの解析コストが増加します。
フィールドの追加・削除がresultMap設定と一致しない可能性があります。
SELECTで不要な列を除外することを推奨します:SQLステートメントのSELECT部分には必要な列のみを記述してください。不要な列があると、データベースが再びテーブルにアクセス(データページに入り、要求された特定の列を取得する)する必要が生じ、I/Oが増加します。
パーティションテーブルを扱うSQLステートメントでは、述語にパーティションキーを必ず含める必要があります。
count(列名)やcount(定数)を使用してcount(*)を置き換えることは推奨されません。count(*)はSQL92で定義された標準的な行数を集計する構文であり、データベースやNULL値、NOT 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句を含むクエリでは、中間結果セットは10,000行以内に制限します。大規模な結果セット(中間結果セットが10,000行を超える場合)のソートやグループ化は、アプリケーション側で実装してください。
パラレル数を設定する際、最適なパラレル数はそのテーブルのシャーディング数です。
WHERE条件でテーブルフィールドに対する算術演算や関数計算を行うことは推奨されません。SQL内での変数への代入を避けてください。特に分散処理において、結果を変数に代入することは避けてください。
SQLステートメント内の条件フィールドのデータ型は一貫している必要があります。暗黙的な型変換を避けてください。
SQLステートメント内の
SELECT投影フィールドでデータベースの予約語を使用することは禁止されています。