It's not clear why you would want to rewrite the query to eliminate the IN list. The query could be rewritten to replace the col IN (literal list)
predicate, but that won't improve performance.
If you are looking to improve performance, it's much more likely you'd want to eliminate the
NOT EXISTS (correlated_subquery)
predicate, and replace it using an "anti-join" pattern, something like this:
SELECT t1.*
FROM kx_examenes_diagnostico.examenes t1
LEFT
JOIN kx_examenes_diagnostico.examenes_aplicados t2
ON t2.examen_id=t1.examen_id
AND t2.alumno_id=812
WHERE t1.examen_id IN (1,2,3,4,5,10,11,12,13,50,159,635,456,780,12,63,45)
AND t2.examen_id IS NULL
The "anti-join" pattern is an outer join (to include rows from t1
that didn't have any matching rows in t2
) combined with a predicate (WHERE clause) that eliminates rows that did have a match.
For optimum performance of this particular query, you'd likely want indexes
... ON examenes (examen_id)
... ON examenes_aplicados (examen_id, alumno_id)
Depending on the cardinality of the alumno_id
column, this index might be better:
... ON examenes_aplicados (alumno_id, examen_id)
Either of those two indexes on examenes_aplicados
are "covering indexes", which means that MySQL can satisfy the query by accessing index pages, without a need to visit the pages in the underlying table. We'd expect MySQL EXPLAIN
to show "Using index
" for the access of that table.
UPDATE:
I avoided answering the questions you asked, and answered a fundamentally different question. To answer the questions you asked:
Q: do i have to use OR's?
No, you don't have to use the OR keyword. The IN list can be replaced with an equivalent predicate that does not use any OR
keyword.
Q: Is possible?
Yes, it is possible to replace the IN (list)
predicate with an EXISTS
clause. But you do not want to do that, unless your goal is horrendous performance, and you have a desire for the DBA to hunt you down to chastise you, publicly humiliate you, and beat you about the head.