まず、データベースはこれに最適な場所ではないと感じています。あなたのより大きなリストが電子メールを送信している間(私はあなたの麻痺の試みのために非常に大規模に推測しています)、別の電子メールの受信者への送信を制限したくないので、一時的なテーブルを使用する必要があります以前の郵送。
ここでは、アドレスのリストを維持するためのキャッシュ、または共有メモリリソースとして機能するサーバーが当然の選択です。
ただし、データベースで行うことはできます。私の理解では、1つのメールアドレスが複数回存在する場合は、過去に送信されていないことを確認するだけなので、それほど重要ではありません。ロックポリシーがないと、同じアドレスに同時に送信する複数のスクリプトの競合状態を実際に制御することはできません。ただし、インデックスを使用することで、より効率的にすることができます。実際のアドレスにインデックスを付けるのではなく、アドレスのCRC32ハッシュ(4バイトのメモリしか必要としない32ビットの符号なし整数にすることができます)を使用して新しい列を作成します。CRC32アプローチを使用すると、誕生日のパラドックスのため、クエリの電子メールアドレスも確認する必要があります。
例えば:
SELECT COUNT(*) FROM email_addresses
WHERE email_address_crc = CRC32(?address)
AND email_address = ?address
効率的なものがあると、競合状態に対処するのに役立ちますが、前に述べたように、各電子メールの送信中にデータベースをロックして、正確なリストを維持できるようにすることが唯一の方法です。残念ながら、これは拡張性がなく、電子メールを送信する並列タスクがあると、おそらく役に立たないことを意味します。
以下のコメントに応じて編集します。
コメントで指摘されているように、私は実際に、ロックソリューションに代わるsvdrの代替案に取り組むのを忘れていました。メールアドレスを含む一意のインデックス(またはキャンペーンIDとアドレスを含む複合インデックス)は、アドレスが存在する場合、実際にMySQL例外をスローするため、並列スクリプトが同じアドレスに送信される実用的なソリューションになります。同時。ただし、スクリプト「try's」がメールを送信する前にアドレスを入力すると、SMTPエラーやネットワークの問題が原因でメールが送信されないなどの例外を処理するのは非常に困難です。これにより、受信者がメールを受信できなくなる可能性があります。また、これを提供するのは非常に単純なINSERTとSELECTであり、MySQL例外をトラップするだけで問題ありません。
もう1つの考慮事項は、パフォーマンス上の理由から、電子メールアドレスフィールドを完全にインデックス化する必要があることです。INNODBを使用する場合、この制限は767バイトです。電子メールアドレスの最大有効長は254(VARCHARを使用する場合は長さ+1バイト)です。巨大な主キーがなければ、問題はありません。
インデックスのパフォーマンスにも対処する必要があり、CHARとVCHARを評価する必要があります。CHARフィールドでのインデックスルックアップは、通常、同等のVCHARルックアップよりも15%〜25%高速です。使用するテーブルエンジンによっては、固定幅のテーブルサイズも役立ちます。
要約すると、はい、非ロックソリューションは機能しますが、正確な要件を使用して慎重にテストおよび評価する必要があります(実際のシナリオは、SOの質問よりも複雑であると想定しているため、詳細についてコメントすることはできません)。回答の最初の行で述べたように、データベースはこれに最適な場所ではなく、キャッシュまたは共有メモリスペースの方が効率的で実装が簡単であると私は信じています。