Saya terkejut bahwa keduanya cepat. Saya sarankan menggantinya dengan 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);
Dan untuk yang kedua:
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)
)
Untuk keduanya, Anda menginginkan dua indeks:ips_fatura(ips_usuario_id)
dan ips_fatura(ips_usuario_id_titular)
. Anda dapat memeriksa penjelasannya untuk memastikan bahwa EXISTS
sedang menggunakan indeks. Jika tidak, rilis MySQL yang lebih baru menggunakan indeks untuk 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);
Dalam kedua kasus (EXISTS
atau IN
) tujuannya adalah untuk melakukan "semi-join". Artinya, hanya mendenda baris pertama dengan kecocokan daripada semua kecocokan. Ini adalah efisiensi yang penting, karena memungkinkan kueri untuk menghindari penghapusan duplikasi.
Saya akan berspekulasi bahwa masalahnya adalah pengoptimalan or
-- biasanya ini menghasilkan JOIN
yang tidak efisien algoritma. Namun, mungkin MySQL pintar dalam kasus pertama Anda. Tetapi penambahan IS NULL
ke meja luar membuangnya.