-1

十分に単純に思えます。MBR と MBR_new の 2 つのテーブルがあります。MBR_new に一致する電子メール レコードがない MBR の各レコードを見つける必要があります。

$result = $db->query("
SELECT a.NICK
FROM MBR as a
LEFT JOIN   
MBR_new as b
ON b.email = a.EMAIL
WHERE b.email IS NULL;
");

while ($obj = $result->fetch_object()) {

    echo "No e-mail found for user $obj->NICK<br />";
}

これによりエラーは発生しませんが、無限ループに陥っているようです。どうしたの?

4

1 に答える 1

1

おそらく無限ループではなくemail、MBR_new テーブルの結合列にインデックスを付けていないため、2 つの埋め込みテーブル スキャンです。テスト エントリが非常に少ないテーブルでクエリを試しましたか?

そのようなインデックスがない場合、を使用するNOT IN(subquery)と、MBR_new テーブル内の既存の電子メールだけに対して、一時的でコンパクトな一意のインデックスが作成されます。

また、MBR_new に同じメールアドレスを持つメールが複数回ありませんか (これにより、結合が爆発する可能性があります。

テーブル bの列のデータ型にも注意emailしてください: インストールでインデックス可能ですか (テーブルのストレージ形式によって異なります: 妥当な制限のある VARCHAR(n) ですか? テーブル a と同じタイプですか?)

また、結果セットに同じ EMAIL アドレスが何回表示されると思いますか? 1 回だけの場合は、select に「DISTINCT」を追加します。これにより、クエリ オプティマイザーは、テーブル a の次の個別の電子メールにスキップできることをすぐに認識し、一致が見つかったらテーブル b のそれ以降のスキャンを無視します。 .

また、注意してください: テーブル A と B に空のメール エントリがありますか? 最初に一意の ID に関連付けられた電子メール アドレスを含むテーブルを生成し、次にこの ID をテーブル A と B でのみ使用するのは安全ではないでしょうか? (文字列の外部結合は非常に遅いです)。

于 2012-07-17T23:05:18.170 に答える