Question

i have an SQL Requests:

SELECT DISTINCT id_tr 
FROM planning_requests a 
WHERE EXISTS(
        SELECT 1 FROM planning_requests b 
        WHERE a.id_tr = b.id_tr 
        AND trainer IS NOT NULL 
        AND trainer != 'FREE' 
      ) 
AND EXISTS(
        SELECT 1 FROM planning_requests c
        WHERE a.id_tr = c.id_tr 
        AND trainer IS NULL 
    )

but this requests take 168.9490 sec to execute for returning 23162 rows of 2545088 rows should i use LEFT JOIN or NOT IN ? and how can i rewrite it thx

Was it helpful?

Solution

You can speed this up by adding indexes. I would suggest: planning_requests(id_tr, trainer).

You can do this as:

create index planning_requests_id_trainer on planning_requests(id_tr, trainer);

Also, I think you are missing an = in the first subquery.

EDIT:

If you have a lot of duplicate values of id_tr, then in addition to the above indexes, it might make sense to phrase the query as:

select id_tr
from (select distinct id_tr
      from planning_requests
     ) a
where . . .

The where conditions are being run on every row of the original table. The distinct is processed after the where.

OTHER TIPS

I think your query can be simplified to this:

SELECT DISTINCT a.id_tr 
FROM planning_requests a
JOIN planning_requests b
ON b.id_tr = a.id_tr
AND b.trainer IS NULL
WHERE a.trainer < 'FREE'

If you index planning_requests(trainer), then MySQL can utilize an index range to get all the rows that aren't FREE or NULL. All numeric strings will meet the < 'FREE' criteria, and it also won't return NULL values.

Then, use JOIN to make sure each record from that much smaller result set has a matching NULL record.

For the JOIN, index planning_requests(id_tr, trainer).

It might be simpler if you don't mix types in a column like FREE and 1.

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