SQL最適化(1)

2336 ワード

最近、データベースsqlの最適化がお客様の体験に大きく向上していることがわかりました.以前のDBUtils+をプロジェクトで反射してクエリする方法をSpring Templateに変更します.効率がずいぶん上がった.そのため,データベースクエリの最適化をまとめる必要があると考える.
1.実際の状況に基づいてデータベースインデックスを作成する
よく使用されるname、id、dateなどのフィールドにインデックスを作成します.具体的な状況は業務によって確定する.複数のフィールドにインデックスを作成することもできます
2.プリコンパイルクエリの使用
一般的なバックグラウンドプログラムは,ユーザの入力に基づいて動的SQLを実行するが,この場合SQL注入ホール攻撃がある可能性がある.したがって、SQLのプリコンパイルが一般的に要求され、DBMSは最初の実行時に文クエリーの最適化とプリコンパイルを行います.このようにSQLを実行するときは、プリコンパイル結果をそのまま使用して、実行速度を向上させます.
3.Where文での接続順序の調整
DBMSは一般にWhere文を下から上への順序で解析するが,この原理表による接続は他のwhere条件の前に書くことが望ましい.最大数の記録をフィルタリングする条件はWhere句の末尾に書かなければならない.
4.できるだけ複数のSQL文を1つのSQLに圧縮する
SQLを実行するたびにネットワーク接続を確立し、権限検証を行い、SQL文のクエリー最適化を行い、実行結果を送信するプロセスは非常に時間がかかるため、一般的な業務が実行可能な条件下で複数の文を1つのSQL文に圧縮する.
5.havingをWhereで置き換える
havingを使用しないでください.havingはすべてのレコードを取得した後に結果セットをフィルタしますが、whereは実際に集約する前にのみ使用します.havingは一般的に集約関数に用いられる
6.テーブルの別名の使用
SQL文に複数のテーブルを接続する場合は、テーブルの別名を使用し、各カラム名に別名を接頭辞することで、解析時間を短縮し、カラム名の曖昧さによるエラーを回避できます.
7.inとexistsは一般的にexistsを使用します.inはインデックスを移動しないためです.
8.インデックスに計算を使用しない
where句では、インデックスが関数の一部である場合、DBMSのオプティマイザはインデックスを使用せずに全テーブルクエリーを使用します.
     //    :
select * from person where salary*12>25000(salary    )

  //    :      
select * from person where salary>25000/12(salary    )

9.unionをunion allで置き換える
SQL文にunionの2つのクエリー結果が必要な場合は、union allが一般的に使用されます.unionとunion allの違いは、unionがデータに対してdistanctの動作を行うことであり、このdistanctの動作の速度は既存のデータの数に依存し、数が大きいほど時間も遅くなる.一方,いくつかのデータセットについては,データセット間のデータが互いに重複しないことを確保するには,基本的にO(n)のアルゴリズムの複雑さである.UNIONにはもう一つの役に立つことがあります.私たちは大量のデータのクエリーで、もし
select * from c_cons where cons_id in ('691339365','3387785','3387954');

このようなクエリ文は、全テーブルスキャンを引き起こし、UNIOALLを使用して代替できます.
select * from c_cons where cons_id='691339365' 
UNION ALL 
select * from c_cons where cons_id='3387785' 
UNION ALL 
select * from c_cons where cons_id='3387954'

これにより、inクエリを使用するよりもクエリが大幅に速くなり、テーブル全体のスキャンは行われません.
10.SQLで暗黙的なタイプ変換を避ける
1つのテーブルのインデックスフィールドがwhere条件として使用されている場合、暗黙的なタイプ変換が行われている場合、このインデックスフィールドは認識されません.暗黙的なタイプも計算に属するため、インデックスは全テーブルスキャンを使用します.
11.検索範囲が広すぎるのを防ぐ
is not nullを使用するか、判断に等しくない場合、オプティマイザが一致するレコード数が即時演算子を使用しすぎると仮定した場合、「a%」はインデックスを使用し、「%a」と「%ac」は全表掃面を使用するため、「%a」と「%ac」は使用しないでください.