<条件 A> に一致し、<条件 B> に一致しない行がテーブルに含まれているかどうかを効率的に確認したいのですが、条件は任意です。
Oracleでは、これはほとんど機能します:
select count(*) from dual
where exists (
select * from people
where (<condition A>)
and not (<condition B>)
);
-- returns zero if all rows that match <condition A> also match <condition B>
-- (well, almost)
問題は恐ろしいヌル値です。<condition A> がname = 'Aaron'で、 <condition B> がage = 21であるとしましょう。このクエリは、年齢が 21 歳以外の Aaron を正しく識別しますが、年齢が null の Aaron を識別できません。
これは正しい解決策ですが、数百万のレコードを持つテーブルでは時間がかかる場合があります。
select (
select count(*) from people
where (<condition A>)
) - (
select count(*) from people
where (<condition A>)
and (<condition B>)
) from dual;
-- returns zero if all rows that match <condition A> also match <condition B>
-- (correct, but it is s l o w...)
残念ながら、この 2 つの条件は恣意的で、複雑で、変化するものであり、通常は私の手に負えません。それらはユーザー検索からアプリケーションの永続化フレームワークから生成され、ユーザーに合わせてインデックスを維持しようとしますが、多くの場合、大きなテーブル スキャンが発生します (そのため、"exists" 句を含む最初のクエリは2 番目よりもはるかに高速です。一致するレコードが 1 つ見つかるとすぐに停止でき、2 つの別々のスキャンを実行する必要はありません)。
ヌルを気にせずにこれを効率的に行うにはどうすればよいですか?