ホームページ >データベース >mysql チュートリアル >MySQLの数千万ビッグデータに対するSQLクエリ最適化手法を詳しく解説

MySQLの数千万ビッグデータに対するSQLクエリ最適化手法を詳しく解説

藏色散人
藏色散人転載
2019-12-21 17:53:482547ブラウズ

MySQLの数千万ビッグデータに対するSQLクエリ最適化手法を詳しく解説

1. クエリを最適化するには、テーブル全体のスキャンを避けるようにしてください。まず、where と order by に関係する列にインデックスを作成することを検討してください。

2. where 句でフィールドの null 値を判断しないようにしてください。そうしないと、エンジンはインデックスの使用を断念し、次のような完全なテーブル スキャンを実行します: select id from t where num is nullデフォルト値 0 を設定し、テーブルの num 列に null 値がないことを確認してから、次のようにクエリを実行します: select id from t where num=0

3。 where 句で != または <> 演算子を使用しない場合、エンジンはインデックスの使用を断念し、テーブル全体のスキャンを実行します。

4. 条件を接続するために where 句で または を使用することは避けてください。そうしないと、エンジンはインデックスの使用を断念し、次のような完全なテーブル スキャンを実行します: select id from t where num=10 または num =20 OK 次のようなクエリ: select id from t where num=10 Union all select id from t where num=20

5.in と not in も注意して使用する必要があります。そうしないと、フル テーブル スキャン。例: select id from t where num in(1,2,3) 連続値の場合、 between を使用できる場合は in を使用しないでください: select id from t where num between 1 ~ 3

6. 次のクエリもすべてのテーブル スキャンの結果になります: select id from t where name like '%李%' 効率を向上させるために、全文検索を検討できます。

7. where 句でパラメータが使用されている場合、テーブル全体のスキャンも発生します。 SQL はローカル変数を実行時にのみ解決するため、オプティマイザはアクセス プランの選択を実行時まで延期できず、コンパイル時に選択を行う必要があります。ただし、アクセス プランがコンパイル時に構築される場合、変数の値はまだ不明であり、インデックス選択の入力として使用できません。たとえば、次のステートメントは完全なテーブル スキャンを実行します: select id from t where num=@num. これを変更して、クエリでインデックスを使用するように強制することもできます: select id from t with(index(index name)) where num =@num

8 。where 句内のフィールドに対して式操作を実行しないようにする必要があります。実行すると、エンジンがインデックスの使用を断念し、テーブル全体のスキャンが実行されます。例: select id from t where num/2=100 を次のように変更する必要があります: select id from t where num=100*2。

9. where 句内のフィールドに対して関数演算を実行しないようにしてください。関数演算を実行すると、エンジンがインデックスの使用を断念し、テーブル全体のスキャンが実行されます。例: select id from t where substring(name,1,3)='abc'、名前が abc で始まる ID は次のように変更する必要があります: select id from t where name like 'abc%'。

10. where 句の「=」の左側で関数、算術演算、その他の式演算を実行しないでください。実行しないと、システムがインデックスを正しく使用できない可能性があります。

11. インデックス フィールドを条件として使用する場合、インデックスが複合インデックスの場合、システムが確実にインデックスを使用するようにインデックスの最初のフィールドを条件として使用する必要があります。そうでない場合、インデックスはは使用されず、フィールドの順序はインデックスの順序とできる限り一致する必要があります。

12. 意味のないクエリは書かないでください。たとえば、空のテーブル構造を生成する必要がある場合: selectcol1,col2 into #t from t where 1=0, このタイプのコードは結果を返しません。設定されていますが、システム リソースを消費する場合は、create table #t(…) に変更する必要があります。

13. 多くの場合、in の代わりにexists を使用するのが良い選択です: select num from a where num in(select num from b)。これを次のステートメントに置き換えます: select num from a where names( b から 1 を選択します (num=a.num)。

14. すべてのインデックスがクエリに有効であるわけではありません。SQL はテーブル内のデータに基づいてクエリを最適化します。インデックス列に大量の重複データがある場合、SQL クエリはインデックスを使用できないことがあります。性別フィールドがあり、ほぼ半分が男性、半分が女性であるため、インデックスが性別に基づいて構築されたとしても、クエリの効率には影響しません。

15. インデックスは多ければ多いほど良いです。インデックスにより、対応する選択の効率は向上しますが、挿入または更新中にインデックスが再構築される可能性があるため、挿入と更新の効率も低下します。 ? インデックス作成には慎重な検討が必要であり、状況によって異なります。 1 つのテーブルに 6 つを超えるインデックスを持たないことが最善ですが、多すぎる場合は、一般的に使用されない一部の列にインデックスを構築する必要があるかどうかを検討する必要があります。

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

17. 数値フィールドを使用するようにしてください。フィールドに数値情報のみが含まれる場合は、文字フィールドとして設計しないようにしてください。これにより、クエリと接続のパフォーマンスが低下し、ストレージのオーバーヘッドが増加します。これは、エンジンがクエリや接続を処理するときに文字列内の各文字を 1 つずつ比較し、数値型の場合は 1 回の比較だけで十分であるためです。

18. char/nchar の代わりに varchar/nvarchar をできるだけ使用してください。これは、第一に、可変長フィールドの記憶領域が小さく、記憶領域を節約できるためです。第 2 に、クエリの検索効率が比較的高くなります。小さなフィールドは高い、明らかに高い。

19. select * from t をどこでも使用せず、「*」を特定のフィールド リストに置き換え、未使用のフィールドを返さないでください。

20. 一時テーブルの代わりにテーブル変数を使用してみてください。テーブル変数に大量のデータが含まれている場合は、インデックスが非常に制限される (主キー インデックスのみ) ことに注意してください。

21. システム テーブル リソースの消費を減らすために、一時テーブルを頻繁に作成および削除することは避けてください。

22. 一時テーブルは使用できないわけではなく、たとえば、大きなテーブルやよく使用されるテーブル内の特定のデータ セットを繰り返し参照する必要がある場合など、一時テーブルを適切に使用すると、特定のルーチンの効率が向上します。ただし、1 回限りのイベントの場合は、エクスポート テーブルを使用することをお勧めします。

23. 一時テーブルを作成するときに、一度に挿入されるデータの量が多い場合は、create table の代わりに select into を使用すると、大量のログが発生して速度が向上するのを避けることができます。システムを容易にするために、データの量は大きくありません。テーブル リソースの場合は、最初にテーブルを作成してから、それを挿入する必要があります。

24. 一時テーブルを使用する場合は、ストアド プロシージャの最後にすべての一時テーブルを明示的に削除する必要があります。最初にテーブルを切り捨ててから、テーブルを削除します。これにより、システム テーブルの長期ロックを回避できます。 。

25. カーソルは効率が悪いため、カーソルの使用は避けてください。カーソルで操作するデータが 10,000 行を超える場合は、データの書き換えを検討してください。

26. カーソル ベースの方法または一時テーブルの方法を使用する前に、まず問題を解決するためのセット ベースのソリューションを探す必要があります。通常、セット ベースの方法の方が効果的です。

27. 一時テーブルと同様に、カーソルは使用できないわけではありません。小規模なデータ セットで FAST_FORWARD カーソルを使用することは、特に必要なデータを取得するために複数のテーブルを参照する必要がある場合、他の行ごとの処理方法よりも優れていることがよくあります。結果セットに「合計」を含むルーチンは、通常、カーソルを使用するよりも高速です。開発時間が許せば、カーソルベースの方法とセットベースの方法の両方を試して、どちらの方法がより効果的に機能するかを確認できます。

28. すべてのストアド プロシージャとトリガーの先頭で SET NOCOUNT ON を設定し、最後に SET NOCOUNT OFF を設定します。ストアド プロシージャとトリガーの各ステートメントの後に DONE_IN_PROC メッセージをクライアントに送信する必要はありません。

29. 大規模なトランザクション操作を避け、システムの同時実行性を向上させるようにしてください。

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

以上がMySQLの数千万ビッグデータに対するSQLクエリ最適化手法を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はruoxiaozh.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。