千万ビッグデータSQLクエリの最適化、いくつかの経験をmysql--

主な内容:

1:クエリの最適化やwhere句(注)

2:使用する際に注意すべきのようなステートメント

3:文の代わりに声明

4:インデックスを使用するか、メモを作成します

ユーザテーブル一万人の加入者を持っていると仮定します。主キーが1000000.numです

1:クエリの最適化は、全表スキャンを回避しようとしてください、あなたは最初の場所と順番に関与列でインデックスを作成することを検討すべきです。

なぜなら:インデックスは、クエリの速度に決定的な影響を与えています。

2:where句にNULL値を決定フィールドに避けるようにしてください。それ以外の場合は、エンジンがインデックスと全表スキャンを使用してあきらめてしまいます。

例えば:numはnullであるユーザからIDを選択します。numが、テーブルには、その後のクエリを実行し、NULL値ではないことを確認し、デフォルト値0にこのフィールドを設定することができます。

SQL如下:ユーザここでNUM = 0からIDを選択します。

(データベーステーブル10と仮定し、次のような場合を考えてみましょうすべてのデータならば、最悪の場合、インデックスがないと、クエリは、テーブル全体をスキャンします。、DBMSのページサイズは4Kで、100件のレコードを格納6レコードをページがメモリにない、必要が10読み込む 10と、4ページ10のために必要なディスク上にランダムに分布する4つのページ、 4 I / O各ディスクI / O時間を仮定すると、10ミリ秒(データ送信時間を無視して)でありますB-Treeインデックスの設立は、唯一log100する必要がある場合は、100Sの合計(しかし、実際にはかなり良くは)。(10 ^ 6)は=ページの読み込み、最悪の場合には時間がかかり30msのは。これが3回ありますインデックスは、多くの時間を結果をもたらす、あなたのアプリケーションのSQLクエリが遅いとき、あなたは、インデックスを構築することができるかどうかを考える必要があります)

3:where句=または<>シンボル操作で避けるべきです!そうしないとエンジンがインデックスの使用を放棄し、その後全表スキャン。

4:インデックスと全表スキャンを使用してあきらめて回避またはwhere句、またはリードに条件への接続に使用するようにしてください。または組合は、すべての労働組合の代わりに使用することができます。

たとえば:NUM = 10またはNUM = 20この文王numはエンジンがインデックスを放棄させ、ユーザからのIDを選択するが、全表スキャンに処理されます。

または組合は、すべての労働組合の代わりに使用することができます。次のように:

ユーザからIDを選択してここでNUM = 10。

労働組合のすべて

ユーザからIDを選択してここでNUM = 20。

(Nuion組合との差の全てと、ここに行きません)

5:中には、注意して使用する必要があるとないで、それ以外の場合は、全表スキャンにつながります。

配列の連続のために、あなたの代わりに。間を使用して...とすることができます。

例えば:

ユーザからIDを選択する場合にNUM(1,2,3)。

連続等と...と...の代わりに使用することができます。次のように:

ユーザからIDを選択ここで、1と3の間にNUM。

6:ために支払われるべきであるように

次のクエリは、フルテーブルクエリにつながります。

名「%の三」のような、ユーザからのIDを選択します。

あなたのアカウントにフルテキスト検索を取って、効率を改善したい場合。たとえば、Solrのかlunceneのため

そして、あなたはインデックスに次のクエリを使用します。

名「张の%」のような、ユーザからのIDを選択します。

7:句パラメータは、に注意を払う必要があります

あなたはWHERE句にパラメータを使用する場合、全表スキャンにつながります。SQLは実行時にのみ、ローカル変数を解決しますので。オプティマイザが実行するためのアクセス・プランの選択を延期することができない場合でも、あなたは、コンパイル時に選択する必要があります。しかし、コンパイル時にアクセス・プランを確立する場合、変数の大きな値は不明であるため、索引項目として選択することはできません。

次の文は、全表スキャンを実行しますこのような:

ここで、NUM = @numユーザからIDを選択

最適化、我々はnumは、主キーである知っています。それはインデックスです。

だからではなく、インデックスを使用することができ、クエリを強制:

ユーザから選択する場所(指数(インデックス名))NUM = @num ID。

8:エンジンがインデックスと全表スキャンを使用してあきらめてしまいますWHERE句の式のフィールドの操作を避けるようにしてください。

例如:ここで、NUM / 2 = 100、ユーザからIDを選択

次のように改正されなければなりません。

ユーザからIDを選択してここでNUM = 100 * 2。

9:どこエンジンがインデックスを放棄するようになりますフィールドの機能動作の句、およびフルテーブルスキャンの愛を避けるようにしてください。

例えば:

ユーザーストリング(名前、1,3)=「ABC」からIDを選択し、フレーズの意味は、実際にSQLクエリ名は、ABCのユーザーIDで開始されます

(注:この関数のサブストリング(フィールド、開始、終了)はMySQLを取られます)

次のように改正されなければなりません。

名「のABC%」のような、ユーザからのIDを選択します。

10:where句「=」左、算術演算、またはその他の式で機能しない、またはシステムが適切にインデックスが動作しない可能性が

11:複合インデックスのクエリ注意

時間内にインデックスフィールドを使用する条件として、インデックスは複合インデックスであるならば、あなたはそれ以外の場合はインデックスが使用されませんので、システムを確実にするために、この時間を利用しての条件として、最初のフィールドにインデックスを使用しなければならない、とする必要があり、可能な限り一貫性のあるフィールドとインデックス付きの順序ましょう。

12:無意味なクエリを記述しないでください。

たとえば、次のユーザーテーブルとして、空のテーブル構造や構成を生成する必要があります(注:同じテーブル構造、新しく生成された新しいテーブルと古いテーブル構造のいとこ)

ユーザ1 = 0からNEWTABLEにCOL1、COL2、COL3を.....選択

上記の行のSQLを実行した後、任意の結果セットを返しますが、システムリソースを消費しません。

次のように改正されなければなりません。

テーブルNEWTABLE(....)この文を作成します。

13:それは多くの場合、代わりに存在して使用することに適しています。

例えば:

ここで、NUM(NEWTABLEからNUMを選択)で、ユーザからNUMを選択します。

代わりに、次のステートメントを使用することができます。

(NEWTABLEのB b.num = a.numからNUMを選択)存在するユーザAからNUMを選択します。

14:すべてのインデックスが有効なクエリ、SQLクエリの最適化は、テーブル内のデータに基づいてインデックス嘘(インデックス付きフィールド)は、重複データの多くを持っている場合、SQLクエリがインデックスを使用して行っていないかもしれわけではありません。テーブルのフィールドのセックス、男性、女性のほぼ半分ずつの場合。インデックスは、クエリの効率あまり効果の性別に作成されている場合でも。

15:索引の作成は、注意すべきです

インデックスが作成されていない、より良いです。インデックスが適切なクエリの効率を改善するだけでなく、挿入および更新の効率を低下させることができますが。それは、インデックスを再構築または変更されますときにインデックスを挿入または更新することができるので。だから我々は慎重に、場合に応じて、インデックスを作成する方法を検討する必要があります。テーブルには、その数が6以上に最高ではありません。あまりにも多くの場合は、あまり一般的に、必要に応じて、列のインデックスを作成するために使用されるのいくつかを検討する必要があります。

ます。https://www.jianshu.com/p/d7f04786ac5eで再現

おすすめ

転載: blog.csdn.net/weixin_34000916/article/details/91132931