Question

How can i "convert" this query for not use IN, i read about in is slow compare it to exists

SELECT * FROM kx_examenes_diagnostico.examenes t1 WHERE NOT EXISTS (
SELECT * FROM kx_examenes_diagnostico.examenes_aplicados t2 WHERE t2.alumno_id=812 AND t2.examen_id=t1.examen_id
) AND t1.examen_id IN (1,2,3,4,5,10,11,12,13,,50,159,635,456,780,12,63,45);

Im using MySQL, i dont know how can i use exist with my values that im compared (inside of in clause) do i have to use OR's? Is possible?

Thanks

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top