どちらかが速いことに驚いています。それらをexists
に置き換えることをお勧めします :
SELECT COUNT(*)
FROM ips_usuario u
WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR
EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id);
そして2番目に:
SELECT COUNT(*)
FROM ips_usuario u
WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR
(u.ips_usuario_id_titular IS NOT NULL AND
EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id)
)
これらの両方に対して、2つのインデックスが必要です:ips_fatura(ips_usuario_id)
およびips_fatura(ips_usuario_id_titular)
。説明をチェックして、EXISTS
であることを確認できます インデックスを使用しています。そうでない場合、MySQLの新しいリリースはIN
のインデックスを使用します :
SELECT COUNT(*)
FROM ips_usuario u
WHERE u.id IN (SELECT f.ips_usuario_id FROM ips_fatura f) OR
u.ips_usuario_id_titular IN (SELECT f.ips_usuario_id FROM ips_fatura f);
いずれの場合も(EXISTS
またはIN
)目標は「半結合」を行うことです。つまり、すべての一致ではなく、一致する最初の行のみを細かく設定します。これにより、クエリで重複の削除を回避できるため、これは重要な効率です。
問題はor
の最適化だと思います -通常、これは非効率的なJOIN
になります アルゴリズム。ただし、最初のケースでは、MySQLが賢いのかもしれません。ただし、IS NULL
の追加 外側のテーブルにそれを捨てます。