52のSQLステートメントのパフォーマンス最適化戦略の要約

1.クエリを最適化するには、テーブル全体のスキャンをできるだけ避け、最初にwhereとorderbyに関係する列にインデックスを設定することを検討してください。

2. where句のフィールドのNULL値の判断を避けるようにしてください。テーブルを作成するときのデフォルト値はNULLですが、ほとんどの場合、NOT NULLを使用するか、0、-1などの特別な値を使用する必要があります。デフォルト値として。

3. where句で*!=または<>演算子を使用しないでください。MySQLは次の演算子にのみインデックスを使用します:<、<=、=、>、> =、BETWEEN、IN、およびその時のいくつかのLIKE。

4.条件を結合するために、またはwhere句を使用しないようにしてください。そうしないと、エンジンがインデックスの使用を中止し、全表スキャンを実行します。UNION結合クエリを使用できます。selectidfromt where num = 10 union all tからidを選択します。num= 20です。

5. inとnotinは注意して使用する必要があります。そうしないと、全表スキャンが発生します。連続値の場合、betweenを使用できる場合はinを使用しないでください。tからidを選択します。numは1から3です。

6.次のクエリでも全表スキャンが発生します。「%abc%」のような名前のtからidを選択するか、「%abc」のような名前のtからidを選択します。効率を向上させるために、全文検索を検討できます。そして、「abc%」のような名前がインデックスのみを使用したtからidを選択します。

7. where句でパラメータを使用すると、全表スキャンも発生します。

8は、where句のフィールドで式演算を実行しないようにし、where句のフィールドで関数演算を実行しないようにする必要があります。

9.多くの場合、inの代わりにexistsを使用することをお勧めします。ここで、num inからnumを選択します(bからnumを選択します)。次のステートメントに置き換えます。existsからnumを選択します(num = a.numであるbから1を選択します)。

10.インデックスは対応する選択の効率を向上させることができますが、挿入または更新中にインデックスが再構築される可能性があるため、挿入および更新の効率も低下させます。そのため、インデックスの構築方法を慎重に検討する必要があります。特定の状況。テーブルのインデックスの数は6を超えてはなりません。インデックスが多すぎる場合は、頻繁に使用されない列にインデックスを作成する必要があるかどうかを検討する必要があります。

11.クラスター化インデックスデータ列の順序はテーブルレコードの物理ストレージの順序であるため、クラスター化インデックスデータ列の更新はできるだけ避けてください。列の値が変更されると、テーブル全体の順序が調整されます。かなりのリソースを消費するレコード。アプリケーションシステムでクラスター化インデックスのデータ列を頻繁に更新する必要がある場合は、インデックスをクラスター化インデックスとして作成する必要があるかどうかを検討する必要があります。

12.可能な限り数値フィールドを使用します。数値情報のみを含むフィールドの場合は、文字として設計しないようにしてください。これにより、クエリと接続のパフォーマンスが低下し、ストレージのオーバーヘッドが増加します。

13.可変長フィールドのストレージスペースが小さいため、char / ncharの代わりにvarchar / nvarcharをできるだけ使用します。これにより、ストレージスペースを節約できます。次に、クエリの場合、比較的小さいフィールドでの検索効率が明らかに高くなります。 。

14.すべてを返すために「」を使用しないことをお勧めします。tから選択し、「*」の代わりに特定のフィールドリストを使用し、未使用のフィールドを返さないでください。

15.クライアントに大量のデータを返さないようにします。データの量が多すぎる場合は、対応する需要が妥当かどうかを検討する必要があります。

16.テーブルエイリアス(エイリアス)を使用する:SQLステートメントで複数のテーブルを接続する場合は、テーブルエイリアスを使用し、各列にエイリアスのプレフィックスを付けてください。このようにして、解析時間を短縮し、列のあいまいさによって引き起こされる文法エラーを減らすことができます。

17.「一時テーブル」を使用して中間結果を一時的に格納する:SQLステートメントを簡略化する重要な方法は、一時テーブルを使用して中間結果を一時的に格納することですが、一時テーブルの利点はこれらをはるかに超えています。一時結果は一時的に一時的に格納されますテーブル、および後続のクエリはtempdbにあります。これにより、プログラム内のメインテーブルの複数のスキャンを回避でき、プログラム実行での「共有ロック」ブロック「更新ロック」を大幅に削減し、ブロックを削減して同時パフォーマンスを向上させます。 。

18.一部のSQLクエリステートメントにNolockを追加する必要があります。読み取りと書き込みは相互にブロックします。同時実行パフォーマンスを向上させるために、一部のクエリにnolockを追加して、読み取り時に書き込みを許可できるようにすることができますが、欠点は読み取られてコミットされない可能性があります。データがダーティです。

nolockを使用するための3つの原則があります:

1.クエリ結果が「挿入、削除、変更」に使用される場合、Nolockを追加できません。

2.クエリテーブルは頻繁なページ分割に属します。nolockは注意して使用してください。

3.一時テーブルを使用すると、OracleのUNDOテーブルスペースと同様の機能を持つ「データフロントシャドウ」を節約できます。一時テーブルを使用すると、同時パフォーマンスを向上させることができます。nolockは使用しないでください。

19.一般的な簡略化ルールは次のとおりです。

5つを超えるテーブル結合(JOIN)がない場合は、一時テーブルまたはテーブル変数を使用して中間結果を格納することを検討してください。サブクエリは慎重に使用し、ビューのネストは深すぎないようにしてください。通常、ビューのネストは2を超えないようにする必要があります。

20.クエリが必要な結果を事前に計算してテーブルに配置し、クエリを実行するときに選択します。これは、病院での入院費の計算など、SQL7.0以前の最も重要な方法でした。

21. ORの表現は複数のクエリに分解でき、複数のクエリはUNIONを介して接続できます。それらの速度は、インデックスが使用されているかどうかにのみ関係します。クエリでジョイントインデックスを使用する必要がある場合、UNIONallの実行効率は高くなります。複数のOR句はインデックスを使用せず、UNIONに書き換えて、インデックスの照合を試みます。重要な問題は、インデックスを使用するかどうかです。

22. INの後の値のリストで、最も頻繁に発生する値を一番上に置き、最も少なく発生する値を後ろに置き、判断の数を減らします。

23.ストアドプロシージャの使用など、ネットワークオーバーヘッドを削減するために、サーバーにデータ処理作業を配置してみてください。

ストアドプロシージャは、コンパイル、最適化、実行プランに編成され、データベースに格納されるSQLステートメントです。これらは制御フロー言語のコレクションであり、もちろん速度は高速です。繰り返し実行される動的SQLの場合、Tempdbに配置される一時ストアード・プロシージャーを使用できます。

24.サーバーに十分なメモリがある場合、構成スレッドの数=接続の最大数+ 5で、効率を最大化できます。それ以外の場合は、構成スレッドの数<接続の最大数を使用して、SQLSERVERスレッドプールを有効にします。数がまだ=最大接続数である場合は、問題を解決します。数+5は、サーバーのパフォーマンスに深刻なダメージを与えます。

25.クエリの関連付けが書き込まれる順序:

select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681’ (A = B ,B = ‘号码’) 

select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681’ and b.referenceid = ‘JCNPRH39681’ (A = B ,B = ‘号码’, A = ‘号码’) 

select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = ‘JCNPRH39681’ and a.personMemberID = ‘JCNPRH39681’ (B = ‘号码’, A = ‘号码’)

26. select count(1)の代わりにexistsを使用して、レコードがあるかどうかを判断してください。count関数は、テーブル内のすべての行をカウントする場合にのみ使用され、count(1)はcount(*)よりも効率的です。

27。 ">"の代わりに "> ="を使用してみてください。

28.インデックスの使用:

1.インデックスの作成は、アプリケーションと併せて検討する必要があります。大きなOLTPテーブルは6つのインデックスを超えないようにすることをお勧めします。

2.インデックスフィールド、特にクラスター化インデックスを可能な限りクエリ条件として使用します。必要に応じて、インデックスindex_nameを使用して、インデックスを強制的に指定できます。

3.大きなテーブルをクエリするときはテーブルスキャンを避け、必要に応じて新しいインデックスを作成することを検討してください。

4.インデックスフィールドを条件として使用する場合、インデックスがジョイントインデックスの場合、システムがインデックスを使用することを保証するために、インデックスの最初のフィールドを条件として使用する必要があります。そうでない場合、インデックスは使用されません。

5.インデックスの保守に注意し、インデックスを定期的に再構築し、ストアドプロシージャを再コンパイルします。

29.次のSQL条件ステートメントの列はすべて適切に索引付けされていますが、実行速度は非常に遅いです。

SELECT * FROM record WHERE substrINg(card_no,1,4)=5378(13)  

SELECT * FROM record WHERE amount/30< 100011秒)  

SELECT * FROM record WHERE convert(char(10),date,112)=19991201’ (10秒) 

分析:

WHERE句の列に対する操作の結果は、SQLの実行時に列ごとに計算されるため、列のインデックスを使用せずにテーブル検索を実行する必要があります。

クエリのコンパイル時にこれらの結果を取得できる場合は、SQLオプティマイザによって、インデックスを使用し、テーブル検索を回避して最適化できるため、SQLは次のように書き直されます。

SELECT * FROM record WHERE card_no like '5378%'(<1秒)

SELECT * FROMレコードWHERE金額<1000 * 30(<1秒)

SELECT * FROM record WHERE date = '1999/12/01'(<1秒)

30.挿入または更新のバッチがある場合は、バッチ挿入またはバッチ更新を使用し、各レコードを更新しないでください。

31.すべてのストアドプロシージャでSQLステートメントを使用できますが、ループを使用して実行することはありません。

例:前月の毎日を一覧表示するには、connect byを使用して再帰的にクエリを実行し、前月の初日から最終日までのループを使用することはありません。

32.最も効率的なテーブル名シーケンスを選択します(ルールベースのオプティマイザーでのみ有効)。

Oracleのパーサーは、FROM句のテーブル名を右から左の順に処理します。最後にFROM句で記述されたテーブル(基本的なテーブル駆動テーブル)が最初に処理され、複数のテーブルがFROM句に含まれます。の場合、ベーステーブルとしてレコード数が最も少ないテーブルを選択する必要があります。

3つを超えるテーブル結合クエリがある場合は、ベーステーブルとして交差テーブルを選択する必要があります。クロステーブルは、他のテーブルによって参照されているテーブルを参照します。

33. GROUP BYステートメントの効率を向上させるために、GROUPBYの前に不要なレコードを除外できます。次の2つのクエリは同じ結果を返しますが、2番目のクエリは明らかにはるかに高速です。

非効率的な:

SELECT JOB , AVG(SAL) 

FROM EMP 

GROUP BY JOB 

HAVING JOB =’PRESIDENT’ 

OR JOB =’MANAGER’ 

効率的:

SELECT JOB , AVG(SAL) 

FROM EMP 

WHERE JOB =’PRESIDENT’ 

OR JOB =’MANAGER’ 

GROUP BY JOB

34. Oracleは常にSQLステートメントを最初に解析し、実行する前に小文字を大文字に変換するため、SQLステートメントには大文字を使用します。

35.エイリアスの使用エイリアスは大規模なデータベースのアプリケーション手法です。テーブル名と列名はクエリ内で文字でエイリアスされ、クエリ速度は接続テーブルの1.5倍です。

36.デッドロックを回避します。ストアドプロシージャとトリガーでは、常に同じ順序で同じテーブルにアクセスします。トランザクションは可能な限り短縮し、トランザクションに関連するデータの量は可能な限り削減する必要があります。トランザクションでのユーザー入力。

37.一時テーブルの使用は避けてください。必要な場合を除いて、一時テーブルの使用は避けてください。代わりに、テーブル変数を使用できます。ほとんどの場合(99%)、テーブル変数はメモリに存在するため、速度が速くなります。一時テーブルよりも、一時テーブルはTempDbデータベースに存在するため、一時テーブルでの操作にはデータベース間の通信が必要であり、これは当然低速です。

38.トリガーを使用しないことをお勧めします。

1.トリガーをトリガーし、トリガーイベント自体を実行することは、リソースを消費するプロセスです。

2.制約を使用して達成できる場合は、トリガーを使用しないようにしてください。

3.異なるトリガーイベント(挿入、更新、削除)に同じトリガーを使用しないでください。

4.トリガーでトランザクションコードを使用しないでください。

39.インデックス作成ルール:

1.テーブルの主キーと外部キーにはインデックスが必要です。

2. 300を超えるデータを含むテーブルには、インデックスが必要です。

3.他のテーブルに接続されることが多いテーブルの場合、接続フィールドにインデックスを確立する必要があります。

4. Where句によく表示されるフィールド、特に大きなテーブルのフィールドには、インデックスを付ける必要があります。

5.インデックスは、選択性の高いフィールドに基づいて作成する必要があります。

6.インデックスは小さなフィールドに作成する必要があります。大きなテキストフィールドや長いフィールドにもインデックスを作成しないでください。

7.複合インデックスの確立には注意深い分析が必要であり、代わりに単一フィールドインデックスの使用を検討してください。

8.複合インデックスのメイン列フィールド、通常は選択性の高いフィールドを正しく選択します。

9.複合インデックスの複数のフィールドが、ANDモードのWhere句に同時に表示されることがよくありますか?単一フィールドのクエリはほとんどまたはまったくありませんか?その場合は、複合インデックスを作成できます。それ以外の場合は、単一フィールドインデックスを検討してください。

10.複合インデックスに含まれるフィールドがWhere句に単独で表示されることが多い場合は、複数の単一フィールドインデックスに分割されます。

11.複合インデックスに3つ以上のフィールドが含まれている場合は、その必要性を慎重に検討し、複合フィールドを減らすことを検討してください。

12.これらのフィールドに単一フィールドインデックスと複合インデックスの両方がある場合は、通常、複合インデックスを削除できます。

13.データ操作が頻繁に行われるテーブルに対してあまり多くのインデックスを作成しないでください。

14.実行計画への悪影響を回避するために、不要なインデックスを削除します。

15.テーブルに作成された各インデックスは、ストレージオーバーヘッドを増加させ、インデックスは、挿入、削除、および更新操作の処理オーバーヘッドも増加させます。さらに、単一フィールドインデックスの場合、複合インデックスが多すぎると、通常は値がありません。逆に、特に頻繁に更新されるテーブルの場合、データの増加と削除のパフォーマンスが低下し、悪影響はさらに大きくなります。大きい。

16.多数の繰り返し値を含むデータベース内のフィールドにインデックスを付けないようにしてください。

40、MySQLクエリ最適化の概要:

遅いクエリログを使用して遅いクエリを見つけ、実行プランを使用してクエリが正常に実行されているかどうかを判断し、常にクエリをテストして、クエリが最適な状態で実行されているかどうかを確認します。

パフォーマンスは常に時間とともに変化します。テーブル全体でcount(*)を使用しないでください。テーブル全体がロックされ、クエリの一貫性が保たれるため、後続の同様のクエリでクエリキャッシュを使用できます。適切な状況では、DISTINCTの代わりにGROUPBYを使用してください。 WHERE、GROUP BY、およびORDER BY句でインデックス付きの列を使用し、インデックスを単純に保ち、複数のインデックスに同じ列を含めないでください。

MySQLが間違ったインデックスを使用することがあります。この場合、USE INDEXを使用して、SQL_MODE = STRICTの使用の問題を確認してください。5レコード未満のインデックスフィールドの場合は、ORではなくUNIONでLIMITを使用してください。

更新前のSELECTを回避するには、INSERT ON DUPLICATEKEYまたはINSERTIGNOREを使用し、UPDATEを使用せず、MAXを使用せず、インデックスフィールドとORDERBY句を使用します。LIMITM、Nは、実際にクエリの速度を低下させる場合があります。 、慎重に使用してください。サブクエリの代わりにWHERE句でUNIONを使用してください。MySQLを再起動した後、データベースをウォームアップして、データがメモリ内にあり、クエリ速度が速いことを確認してください。複数の接続ではなく永続的な接続を検討してください。オーバーヘッドを削減してください。 。

ベンチマーククエリには、サーバーの負荷の使用が含まれます。単純なクエリが他のクエリに影響を与える場合があります。サーバーの負荷が増加した場合は、SHOW PROCESSLISTを使用して、低速で問題のあるクエリを表示します。開発環境で生成されたミラーデータでテスト済みすべての疑わしいクエリ。

41. MySQLバックアッププロセス:

1.セカンダリレプリケーションサーバーからバックアップを作成します。

2.バックアップ期間中にレプリケーションを停止して、データ依存性と外部キー制約の不整合を回避します。

3. MySQLを完全に停止し、データベースファイルからバックアップします。

4.バックアップにMySQLダンプを使用する場合は、バイナリログファイルを同時にバックアップしてください。レプリケーションが中断されていないことを確認してください。

5. LVMスナップショットを信頼しないでください。これにより、データの不整合が発生し、将来的に問題が発生する可能性があります。

6.単一テーブルのリカバリを簡単に実行できるようにするには、データをテーブル単位でエクスポートします(データが他のテーブルから分離されている場合)。

7.mysqldumpを使用する場合は-optを使用してください。

8.バックアップの前にテーブルを確認して最適化します。

9.インポートを高速化するには、インポート中に外部キー制約を一時的に無効にします。

10.インポートを高速化するには、インポート中に一意性の検出を一時的に無効にします。

11.データサイズの増加をより適切に監視するために、各バックアップ後にデータベース、テーブル、およびインデックスのサイズを計算します。

12.自動スケジューリングスクリプトを使用して、レプリケーションインスタンスのエラーと遅延を監視します。

13.定期的なバックアップを実行します。

42.クエリバッファはスペースを自動的に処理しません。したがって、SQLステートメントを作成するときは、特にSQLの最初と最後でスペースの使用を最小限に抑える必要があります(クエリバッファは最初と最後のスペースを自動的にインターセプトしないため)。

43.メンバーがサブテーブルのクエリの標準としてmidを使用するのは便利ですか?一般的なビジネス要件は、基本的にクエリベースのユーザー名に基づいています。通常、ユーザー名は、テーブルを分割するためのハッシュモジュロとして使用する必要があります。

サブテーブルの場合、MySQLのパーティション関数がこれを実行します。これはコードに対して透過的です。コードレベルで実装するのは不合理に思えます。

44.データベース内の各テーブルのIDを主キーとして設定する必要があります。最適なのはINTタイプ(UNSIGNEDを推奨)であり、自動増加AUTO_INCREMENTフラグを設定します。

45.すべてのストアドプロシージャとトリガーの最初にSETNOCOUNT ONを設定し、最後にSET NOCOUNTOFFを設定します。ストアドプロシージャとトリガーの各ステートメントを実行した後、DONE_IN_PROCメッセージをクライアントに送信する必要はありません。

46、MySQLクエリは高速クエリキャッシュを有効にすることができます。これは、データベースのパフォーマンスを向上させるための効果的なMySQL最適化手法の1つです。同じクエリが複数回実行されると、キャッシュからデータを抽出し、データベースから直接データを返す方がはるかに高速です。

47. EXPLAIN SELECTクエリは、効果を追跡および表示するために使用されます。

EXPLAINキーワードを使用して、MySQLがSQLステートメントを処理する方法を通知します。これは、クエリまたはテーブル構造のパフォーマンスのボトルネックを分析するのに役立ちます。EXPLAINクエリの結果には、インデックスの主キーの使用方法、データテーブルの検索方法と並べ替え方法も表示されます。

48. 1行のデータのみが必要な場合は、LIMIT1を使用します。

しばらくの間テーブルにクエリを実行すると、結果が1つしかないことがすでにわかっていますが、カーソルをフェッチする必要がある場合や、返されたレコードの数を確認する場合があるためです。

この場合、LIMIT1を追加するとパフォーマンスが向上します。このようにして、MySQLデータベースエンジンは、レコードに一致する次のデータを検索し続けるのではなく、データを検索した後に検索を停止します。

49.テーブルに適したストレージエンジンを選択します。

myisam:アプリケーションは読み取りと挿入の操作に基づいており、更新と削除はわずかであり、トランザクションの整合性と同時実行性の要件はそれほど高くありません。

InnoDB:トランザクション処理、および同時条件下で必要なデータの整合性。挿入とクエリに加えて、多くの更新と削除が含まれています。(InnoDBは、削除と更新によって引き起こされるロックを効果的に削減します)。

トランザクションをサポートするInnoDBタイプのテーブルの場合、速度に影響を与える主な理由は、AUTOCOMMITのデフォルト設定がオンになっており、プログラムがBEGINを明示的に呼び出してトランザクションを開始しない
ため、各挿入が自動的にコミットされるためです。速度に深刻な影響を与えます。SQLを実行する前にbeginを呼び出すことができ、複数のSQLが1つのトランザクションを形成します(自動コミットがオンになっている場合でも)。これにより、パフォーマンスが大幅に向上します。

50.テーブルのデータ型を最適化し、適切なデータ型を選択します。

原則:通常は小さい方が良いです。単純な方が良いです。すべてのフィールドにデフォルト値を設定する必要があります。nullは避けてください。

例:データベーステーブルを設計するときは、ディスク領域を占有するために、できるだけ小さい整数型を使用してください。(mediumintはintよりも適しています)

たとえば、時間フィールド:日時とタイムスタンプ、日時は8バイトを占め、タイムスタンプは4バイトを占め、その半分のみであり、タイムスタンプの範囲は更新時間に適した1970〜2037です。

MySQLは大量のデータへのアクセスを十分にサポートできますが、一般的に言えば、データベース内のテーブルが小さいほど、クエリの実行速度は速くなります。

したがって、テーブルを作成するときは、パフォーマンスを向上させるために、テーブル内のフィールドの幅をできるだけ小さく設定できます。

例:郵便番号フィールドを定義するときに、CHAR(255)に設定すると、明らかにデータベースに不要なスペースが追加されます。CHAR(6)はタスクを適切に実行できるため、VARCHARを使用する場合でも冗長です。

同様に、可能であれば、BIGINの代わりにMEDIUMINTを使用して整数フィールドを定義する必要があります。また、将来クエリを実行するときにデータベースがNULL値を比較する必要がないように、フィールドをNOTNULLに設定するようにしてください。

「province」や「gender」などの一部のテキストフィールドでは、ENUMタイプとして定義できます。MySQLでは、ENUMタイプは数値データとして扱われ、数値データはテキストタイプよりもはるかに高速に処理されるためです。このようにして、データベースのパフォーマンスを向上させることができます。

51.文字列データ型:char、varchar、テキスト選択の違い。

52.列に対する操作はすべて、データベース関数、計算式などを含むテーブルスキャンになります。クエリを実行するときは、操作を可能な限り等しい符号の右側に移動します。

元のリンク:https//www.cnblogs.com/hlkawa/p/14176545.html

おすすめ

転載: blog.csdn.net/qq_43307934/article/details/111934833