2012-04-11 31 views
1

我被告知用嵌套查询重写下面的查询,而没有连接以获得更好的性能。这是真的吗?如果是这样,如何重写它?如何将其重写为嵌套查询?

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 

这里是表结构。

enter image description here

+1

为什么嵌套查询通常会比联接更好/更差?这真的取决于很多事情。实际问题可能与您选择了太多数据然后使用'distinct'删除重复项相关。你为什么需要“独特”?你可以在外键上显示所有相关的索引吗? – 2012-04-11 13:52:38

+2

我也很好奇。根据我的经验,假设索引设置正确,优化器将充分利用连接。 – moleboy 2012-04-11 13:53:40

+0

如果运行缓慢,请检查执行计划和/或运行SQL事件探查器(不要将其用于生产框,尽管:)以查看扫描发生的位置。一旦你弄清楚了,建议将列上的索引添加到DBA中。但我同意其他关于嵌套查询性能的评论。 – Eugene 2012-04-11 13:54:09

回答

0

让我回答我的问题。我不喜欢这种方式,但在这里我们去...

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 
1

优化应该得到这个权利,但是你可能需要比较原始查询的性能针对这一个:

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 

的不同在purschases表可以消除一些工作,但是我怀疑是否会有那么多蠢事。

什么可以帮助更多的是purchase_invoice (username, outlet_id, company_id)索引。这可以加快速度,因为它将在桌面上为covering index。连接只需查看索引并可跳过阅读实际表格。如果桌子很宽,这会有所帮助。

另请注意索引中列的顺序。我猜0123,也有很多行,并且它在Username上有一个聚簇索引。通过这种方式索引和ct_user将按用户名排序,允许merge join加入两个大表。

此外,请为您的表使用连接语法和有意义的别名,例如c fr company和ug for user_group。它对数据库应该没有关系,但它有助于人类试图阅读你的代码。 此外,ALLCAPS看起来像你的尖叫所有的时间,但也许这只是我:-)

GJ