2

約250,000レコードのusersというテーブルがあります。ステージングと呼ばれる別のテーブルがあり、その中には約75,000レコードが含まれています。ステージングには、msisdnという1つの列しかありません。ステージングの行数がユーザーに存在しないことを確認したいと思います。

小さなデータサブセットでテストした次のクエリがありますが、正常に機能しているようです。

SELECT
    s.*
    FROM staging s
        LEFT OUTER JOIN users u ON u.msisdn=s.msisdn
        WHERE u.msisdn IS NULL

ただし、問題は、25万人のユーザーの完全なリストでこのクエリを実行しようとしたときです。私がそれを止める前にそれは1時間走った。このクエリを最適化する方法はありますか?

ステージングでデータのサブセットに対してクエリの実行を開始しましたが、これはひどく手動です。

SELECT
    s.*
    FROM staging s
        LEFT OUTER JOIN users u ON u.msisdn=s.msisdn
        WHERE u.msisdn IS NULL
    LIMIT 0,10000

msisdnはステージングテーブルの主キーですが、テーブルユーザーの主キーではありません。しかし、それが重要かどうかはわかりません。

4

4 に答える 4

4

まず、MySQL が EXPLAIN コマンドで使用しているインデックスを確認できます。クエリの前に書くだけEXPLAINで、使用しているインデックス (存在する場合) が結果に表示されます。おそらく、250,000 レコードという (比較的) 小さいデータ セットでそれほど遅い場合は、非常に効果的なインデックスを活用していないため、どこにあるかを確認できます。

NOT EXISTSクエリを次のように書き直すことも役立つ場合があります。

SELECT s.* FROM staging s
WHERE NOT EXISTS (SELECT 1 FROM users WHERE users.misdn = s.misdn)
于 2009-08-12T12:58:57.037 に答える
1

msisdn各テーブルの列にインデックスを配置します。の PK ではないためusers、非クラスター化インデックスを配置する必要があります。これにより、クエリが大幅に高速化されます。

于 2009-08-12T12:57:40.547 に答える
1

このクエリを高速化するためにできること:

  • 両方のテーブルで msisdn のインデックスが作成されていることを確認してください
  • テーブルを最適化する
  • * を msisdn に置き換えます
于 2009-08-12T13:05:04.577 に答える
0

これがどれほど速くなるかはわかりませんが、次のようなことを試すことができます。

select msisdn
from staging
where msisdn not in (select msisdn from users)

また、両方のテーブルの msisdn 列にインデックスが存在することを確認してください。それは物事を途方もなくスピードアップするはずです。

于 2009-08-12T12:58:15.973 に答える