本記事では、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に実行計画をバインドしますが、長期的な運用ではSQLロジックの修正を推奨します。過度のHINTは、今後のアップグレードやメンテナンスに一定の影響を及ぼす可能性があります。
DISTINCT、ORDER BY、GROUP BY句を含むクエリでは、中間結果セットは10,000行以内に制限します。大規模な結果セット(中間結果セットが10,000行を超える場合)のソートやグループ化は、アプリケーション側で実装します。
パラレル数を設定する際、最適なパラレル数はそのテーブルのシャーディング数です。
WHERE条件では、テーブルフィールドに対する算術演算や関数計算を行うことは推奨されません。SQL内での変数への代入を避けてください。特に分散処理において、結果を変数に代入することは避けてください。
SQL文における条件フィールドのデータ型は一貫している必要があります。暗黙的な型変換を避けてください。
SQL文の
SELECT投影フィールドでは、データベースの予約語の使用を禁じます。