Reputation: 1599
I was told to rewrite thie following query with a nested query without joins for better performance. Is it true? If so, how to rewrite it?
SELECT distinct A.Company_Name,C.Outlet_Name,
C.Outlet_FCE_ID,D.Usergroup_Name
FROM company A, PURCHASE_INVOICE B,
Outlet C, User_Group D,CT_USER E
WHERE A.Company_ID = B.Company_ID AND B.Outlet_ID = C.Outlet_ID
AND B.Company_ID = C.Company_ID AND B.Username = E.Username
AND E.Usergroup_ID=D.Usergroup_ID
Here is the table structure.
Upvotes: 1
Views: 198
Reputation: 1599
Let me answer my own question. I don't like it this way, but here we go....
SELECT distinct
( SELECT Company_Name
FROM dbo.COMPANY
WHERE Company_ID = p.Company_ID
) AS 'CompanyName' ,
( SELECT Outlet_Name
FROM dbo.OUTLET
WHERE Company_ID = p.Company_ID
AND Outlet_ID = p.Outlet_ID
) AS 'OutletName' ,
( SELECT Outlet_FCE_ID
FROM dbo.OUTLET
WHERE Company_ID = p.Company_ID
AND Outlet_ID = p.Outlet_ID
) 'OutletFCEID' ,
( SELECT Usergroup_Name
FROM dbo.USER_GROUP
WHERE Usergroup_ID IN ( SELECT Usergroup_ID
FROM CT_USER
WHERE Username = p.UserName )
) 'UsergroupName'
FROM dbo.PURCHASE_INVOICE p
Upvotes: 0
Reputation: 10536
The optimizer should get this right, but you may want to compare the the performance of the original query against this one:
select distinct
c.company_name,
o.outlet_name,
o.outlet_fce_id,
ug.usergroup_name
from company c
inner join (select distinct company_id, outlet_id, username from purchase_invoice) i on c.company_id=i.company_id
inner join outlet o
on i.outlet_id = o.outlet_id
and i.company_id = o.company_id
inner join ot_user u on b.username = e.username
inner join user_group ug on u.usergroup_id = d.usergroup_id
The distinct on the purschases table could eliminate some work, but I doublt if there will be that many dupes.
What would help more is an index on purchase_invoice (username, outlet_id, company_id)
. This could speed it up because it would be a covering index on the table. The join would only have to look at the index and could skip reading the actual table. That helps if the table is wide.
Also note the order of columns in the index.I'm guessing that ct_user
also has a lot of rows, and that it has a clustered index on Username
. This way both the index and ct_user
will be sorted on username, allowing a merge join for joining the two big tables.
Also please use join syntax and meaningful aliases for your tables like c fr company and ug for user_group. It shouldn't matter to the database but it defenitely helps humans trying to read your code. Also, allcaps LOOKS LIKE YOUR SCREAMING ALL THE TIME, but maybe that's just me :-)
GJ
Upvotes: 1