sql >> データベース >  >> RDS >> Mysql

最適化のためのMySQLハッシュインデックス

    まず、あなたが提起する特定の質問に対処するために:

    1. CREATE INDEXに記載されているとおり 構文

      したがって、HASHを検討する前に インデックス作成、のみであることに注意する必要があります MEMORYで利用可能 およびNDB ストレージエンジン:そのため、オプションではない場合もあります。

      さらに、IDの組み合わせのインデックスに注意してください およびLookup WHEREのように、単独では最適ではない場合があります 述語はtablea.Elg_IDpart1でもフィルタリングします およびtableb.IDpart1 —これらの列のインデックスを作成することもメリットがあります。

    2. 必要なインデックスタイプがストレージエンジンでサポートされている場合は、必要に応じてそれらを混在させることができます。

    3. インデックスヒント を使用できます MySQLに、オプティマイザーが選択したインデックスとは異なるインデックスを使用するように強制します。

    4. 通常 十分に賢いですが、常にではありません。ただし、この場合、インデックスのカーディナリティは、選択したインデックスを使用する方が適切であると判断された可能性があります。

    現在、使用しているMySQLのバージョンによっては、サブクエリから派生したテーブルに、さらに処理するために使用できるインデックスがない場合があります。その結果、bとの結合になります。 その派生テーブルの完全なスキャンが必要になる場合があります(これがどの程度の問題であるかを正確に判断するには、質問に十分な情報がありませんが、schema1.tableb 150万件のレコードがあることは、それが重要な要因である可能性があることを示唆しています。

    サブクエリの最適化 を参照してください。 詳細については。

    したがって、可能な限り派生テーブルの使用を避けるように努める必要があります。この場合、schema1.tableaを単純に結合できるため、派生テーブルには何の目的もないようです。 およびschema1.tableb 直接:

    UPDATE   schema1.tablea a
        JOIN schema1.tableb b USING (ID, Lookup)
    SET      a.Elg_IDpart1 = b.IDpart1, 
             a.Elg_IDpart2 = b.IDpart2
    WHERE    a.Elg_IDpart1 IS     NULL
         AND a.ID          IS NOT NULL
         AND b.IDpart1     IS NOT NULL
         AND b.Lookup      IS NOT NULL
    ORDER BY ID, Lookup
    

    失われたのは、DISTINCTのフィルターだけです。 レコードですが、重複したレコードは、更新された値を同じ値で再度上書きしようとします。これは効果がありませんが、非常にコストがかかることが判明している可能性があります(特に、そのテーブルに非常に多くのレコードがある場合)。

    ORDER BYの使用 派生テーブルでは、UPDATEの特定の順序を達成するために信頼できないため、無意味でした。 、一方、この改訂バージョンでは、以前の更新を上書きする更新が指定された順序で行われるようになります。ただし、それは必要ですか?おそらく、それを削除して、並べ替え操作を節約することができます。

    WHEREの述語を確認する必要があります 句:それらはすべて必要ですか(NOT NULL a.IDをチェックします およびb.Lookup たとえば、そのようなNULLを考えると、不要です。 レコードはJOINによって削除されます 述語)?

    全体として、これは私たちに次のことを残します:

    UPDATE   schema1.tablea a
        JOIN schema1.tableb b USING (ID, Lookup)
    SET      a.Elg_IDpart1 = b.IDpart1, 
             a.Elg_IDpart2 = b.IDpart2
    WHERE    a.Elg_IDpart1 IS     NULL
         AND b.IDpart1     IS NOT NULL
    

    それでもパフォーマンスが不十分な場合にのみ、インデックス作成をさらに検討する必要があります。関連する列(つまり、JOINで使用される列) およびWHERE 述語)インデックス付き? MySQLで使用するためにインデックスが選択されていますか(1つしか使用できないことに注意してください) ルックアップ用のテーブルごとのインデックス:両方のJOINをテストするため 述語とフィルター述語:おそらく適切な複合索引が必要ですか? EXPLAINを使用して、クエリ実行プランを確認します そのような問題をさらに調査するため。




    1. Oracle行の複数の列でピボットを使用する

    2. AWSRDSでのMySQLデータベースおよびOracleデータベースでのJDeveloperの使用パート3

    3. MySQLにあるテーブルの数を数えるためのクエリ

    4. SELECTリストの他の場所でエイリアスを参照する