Reputation: 1
i have a scenario as below.
Employee table
EmpId X_Id Flag
--------------------------------
1 123 0
Dept table
DeptId D.Name X_Id Flag
----------------------------------------------
1 a 123 0
2 b 123 1
i need to write a query that fetches the rows based on the flag. ie., if flag is 0 in EmpTable, then get only rows which have flag as 0 and if flag is set to 1 in EmpTable, get all rows (with flag as 0 and 1). To achieve this, i have written the below query
SELECT E.EmpId, E.X_Id, D.Did, D.Dname
FROM EmpTable E INNER JOIN DeptTable D
ON E.X_Id = D.X_Id
AND (D.Flag = 0 or D.Flag = E.Flag)
the above query returns correct rows, but as I see it, using OR is not a good idea. the query is slow. Any alternatives to achieve the same with optimal performance??
Upvotes: 0
Views: 145
Reputation: 45096
A reach but maybe worth a try.
Sometimes a join settles on one index.
If you split it up then sometimes it will use separate indexes.
Look at the query plan.
SELECT E.EmpId, E.X_Id, D.Did, D.Dname
FROM EmpTable E
JOIN DeptTable D1
ON E.X_Id = D1.X_Id
JOIN DeptTable D2
ON D2.Flag = E.Flag
OR D2.Flag = 0
SELECT E.EmpId, E.X_Id, D.Did, D.Dname
FROM EmpTable E
JOIN DeptTable D1
ON E.X_Id = D1.X_Id
WHERE D2.Flag = E.Flag
OR D2.Flag = 0
Upvotes: 0
Reputation: 453608
The only obvious alternative is
SELECT E.EmpId,
E.X_Id,
D.Did,
D.Dname
FROM EmpTable E
INNER JOIN DeptTable D
ON E.X_Id = D.X_Id
AND D.Flag = E.Flag
UNION
SELECT E.EmpId,
E.X_Id,
D.Did,
D.Dname
FROM EmpTable E
INNER JOIN DeptTable D
ON E.X_Id = D.X_Id
AND D.Flag = 0
Sometimes rewriting OR
as UNION
can help performance. If that doesn't help you would need to look at the execution plan to see if you are missing any required indexes for example.
Upvotes: 2