PID UID Req Res
1 101 C to
2 101 A from
3 101 B to
4 102 A from
5 102 B from
I want to write a query to get all the records from table which satisfies the below condition.
I want to get UID of all the records where Res=’to’. For these particular UID I want to get records with Req=’A’. I wrote a sample query and it worked also. Please find the query below.
SELECT Res,
UID,
Req
FROM TABLE
WHERE Req = 'A'
AND UID = (SELECT DISTINCT( UID )
FROM TABLE
WHERE Res = 'to')
The problem with the above query is that while running in SQL server 2008, it is running for more than one hour for fetching just 15-20 records. Total number of records is big as this is a production table. I wish to know why the query is long running as well as whether I can get an optimized query for the same.
Thanks,
Prabhath
The reason your query is so slow is that your engine is probably running that subquery for every single row it considers, and that query may be an implicitly aggregating (since it uses DISTINCT). That’s a lot of work to do for each row, and as it gets later into the result set, it is likely doing plenty of swapping to make it happen.
This query joins the table to itself on the condition that the joined row has the same UID and has Res = ‘to’. Rows are filtered based on two factors: having at least one matching row with same UID and Res=’to’, and having Req=’A’.
This will be a very fast solution, and here’s why: Query engines are optimized to eliminate rows from the result set as soon as they can. For rows PID=1, 3, &5, the engine will immediately discard them from consideration (not even perform the join) since Req != ‘A’. For row PID=2, the join will match row 1 and then usually not even continue on to join 3 (since it knows via the DISTINCT keyword (and the fact that no columns from the join are being selected) that matching additional rows in the join would not change the result set). And for PID=4, it won’t match any.