まず、あなたが提起する特定の質問に対処するために:
-
したがって、
HASH
を検討する前に インデックス作成、のみであることに注意する必要がありますMEMORY
で利用可能 およびNDB
ストレージエンジン:そのため、オプションではない場合もあります。さらに、
ID
の組み合わせのインデックスに注意してください およびLookup
WHERE
のように、単独では最適ではない場合があります 述語はtablea.Elg_IDpart1
でもフィルタリングします およびtableb.IDpart1
—これらの列のインデックスを作成することもメリットがあります。 -
必要なインデックスタイプがストレージエンジンでサポートされている場合は、必要に応じてそれらを混在させることができます。
-
インデックスヒント を使用できます MySQLに、オプティマイザーが選択したインデックスとは異なるインデックスを使用するように強制します。
-
通常 十分に賢いですが、常にではありません。ただし、この場合、インデックスのカーディナリティは、選択したインデックスを使用する方が適切であると判断された可能性があります。
現在、使用している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
を使用して、クエリ実行プランを確認します そのような問題をさらに調査するため。