Reputation: 20
I have migrated following query from mssql to mysql.
SELECT employee.ecode, fname, mname, lname
FROM employee
WHERE employee.cmp_dol IS NULL
AND employee.ecode IN
(SELECT leave_log.ecode
FROM leave_log
WHERE (l_acc_code = 11 OR l_acc_code = 21 OR l_acc_code = 31 OR l_acc_code = 41 OR l_acc_code = 51 OR l_acc_code = 61 )
GROUP BY leave_log.ecode, l_date, l_acc_code
HAVING SUM(l_value) <> 0)
AND employee.ecode IN ((SELECT ecode
FROM emp_supervisor
WHERE sup_id = @ecode
AND emp_sup_dol IS NULL)
UNION
(SELECT ecode
FROM emp_project
WHERE proj_emp_dol IS NULL
AND pid IN (SELECT pid
FROM proj_supervisor
WHERE proj_sup_dol IS NULL
AND sup_id =@ecode
AND pid IN (SELECT pid
FROM projects
WHERE p_end_date IS NULL
AND leave_flag=1))))
ORDER BY fname
With the IN statement in query its taking endless time. But when I am replacing it with exists it is giving different output.
Any help will be highly appreciated.
Upvotes: 0
Views: 78
Reputation: 782508
MySQL is very poor at optimizing WHERE IN with a subquery, use a JOIN instead:
SELECT employee.ecode, fname, mname, lname
FROM employee
JOIN (SELECT DISTINCT ecode
FROM emp_supervisor
WHERE sup_id = @ecode
AND emp_sup_dol IS NULL
UNION DISTINCT
SELECT DISTINCT ecode
FROM emp_project
WHERE proj_emp_dol IS NULL
AND pid IN (SELECT pid
FROM proj_supervisor
WHERE proj_sup_dol IS NULL
AND sup_id =@ecode
AND pid IN (SELECT pid
FROM projects
WHERE p_end_date IS NULL
AND leave_flag=1))) e
ON employee.ecode = e.ecode
JOIN (SELECT DISTINCT ecode
FROM (SELECT leave_log.ecode
FROM leave_log
WHERE (l_acc_code IN (11, 21, 31, 41, 51, 61)
GROUP BY leave_log.ecode, l_date, l_acc_code
HAVING SUM(l_value) <> 0) x) l
ON employee.ecode = l.ecode
WHERE employee.cmp_dol IS NULL
ORDER BY fname
You need to use DISTINCT
in the subqueries to avoid multiplying rows in the result if the subquery has duplicates.
Upvotes: 1