2011-12-22 148 views
1

我正在构建一个需要来自5个表的数据的查询。 过去,DBA已经告诉我,从某些性能/内存方面来说,指定列的列表与获取所有列(*)是首选。 我也被告知数据库在FROM子句中有一个表列表来创建一个表(或视图)时执行JOIN操作。FROM子句中的嵌套select语句? Inner Join语句?或只是表名?

现在的数据库目前只有很少的数据,因为我们处于非常初始阶段。所以我不确定我能在实践中衡量性能。 我不是数据库专家。我可以得到我需要的数据。 dillema是,以什么价格。

补充:目前我正在使用MS SQL Server 2008 R2。

我的问题是:

  1. 是否有性能差异及其原因,以下之间: 一个。选择...从tbl1,tbl2,tbl3等简单? (不知何故,我觉得这可能是一个性能问题) b。 SELECT ... FROM tbl1内部连接tbl2 on ...内部连接tbl3 on ... etc(这是否更明确的服务器,并保存性能/内存)? c。 SELECT ... FROM(从tbl1选择x,y,z)作为t1内连接... etc(这会保存anythig吗?还是只是额外的select语句,为服务器和我们创建更多的工作)?

  2. 有没有更好的方法来做到这一点?

下面是两个查询,它们都得到我需要的数据切片。一个包含更多的嵌套选择语句。

我很抱歉,如果他们不是以标准形式写的或无奈地过度复杂 - 希望你可以破译。我尽量让他们尽可能地组织起来。

见解将不胜感激。 感谢您检查了这一点。

5表:devicepool,用户,旅行,TripTracker和订单

查询1(更多选择语句):

SELECT 
     username, 
     base.devid devid, 
     tripstatus, 
     stops, 
     stopnumber, 
     [time], 
     [orderstatus], 
     [destaddress] 

FROM  
((
( SELECT 
      username, 
      devicepool.devid devid, 
      groupid 
    FROM 
      devicepool INNER JOIN users 
      ON devicepool.userid = users.userid 

    WHERE devicepool.groupid = 1 
) 
AS [base] 

INNER JOIN 

(
     SELECT 
       tripid, 
       [status] tripstatus, 
       stops, 
       devid, 
       groupid 

     FROM 
       trips 
) 
AS [base2] 

ON base.devid = base2.devid AND base2.groupid = base.groupid 

INNER JOIN 

(
    SELECT 
      stopnumber, 
      devid, 
      [time], 
      MAX([time]) OVER (PARTITION BY devid) latesttime 
    FROM 
      TripTracker 
) 

AS [tracker] 
ON tracker.devid = base.devid AND [time] = latesttime) 

INNER JOIN 

(
     SELECT 
      [status] [orderstatus], 
      [address] [destaddress], 
      [tripid], 
      stopnumber orderstopnumber 
     FROM [order] 
) 
AS [orders] 

ON orders.orderstopnumber = tracker.stopnumber) 

问题2:

SELECT 
     username, 
     base.devid devid, 
     tripstatus, 
     stops, 
     stopnumber, 
     [time], 
     [orderstatus], 
     [destaddress] 

FROM  
((
( SELECT 
      username, 
      devicepool.devid devid, 
      groupid 
    FROM 
      devicepool INNER JOIN users 
      ON devicepool.userid = users.userid 

    WHERE devicepool.groupid = 1 
) 
AS [base] 

INNER JOIN 

    trips 

ON base.devid = trips.devid AND trips.groupid = base.groupid 

INNER JOIN 

(
    SELECT 
      stopnumber, 
      devid, 
      [time], 
      MAX([time]) OVER (PARTITION BY devid) latesttime 
    FROM 
      TripTracker 
) 

AS [tracker] 
ON tracker.devid = base.devid AND [time] = latesttime) 

INNER JOIN 

    [order] 

ON [order].stopnumber = tracker.stopnumber) 
+2

我肯定会推荐使用**正确的JOIN **语法 - 'INNER JOIN','LEFT OUTER JOIN'等等。这是a)ANSI标准,b)对于读别人你想要做的SQL代码的人来说,它更清楚,更明显; c)你不会意外地通过忘记所涉及的表之间的一些JOIN条件来引入笛卡尔产品。 – 2011-12-22 15:21:48

+0

这可以在SQLEXPRESS和代码上运行。我现在正在使用SQLEXPRESS作为数据库服务器。你能否解释一下这个问题的相关性? – RoyM 2011-12-22 15:29:28

+1

我刚刚检查 - 看起来像SQL Server 2008 R2。我会再次更新。 – RoyM 2011-12-22 15:46:24

回答

5

是否有性能差异以及为什么在以下几点之间:a。 选择...从tbl1,tbl2,tbl3等简单? (不知怎的,我觉得 ,这可能是一个性能打击)b。 SELECT ... FROM tbl1 inner join tbl2 on ... inner join tbl3 on ... etc(这是更明确的 服务器和节省性能/内存)? C。 SELECT ... FROM(从tbl1中选择x,y,z)作为t1内部连接... etc(这个 会保存anythig吗?还是只是额外的select语句,可以为服务器和我们创建更多的 工作) ?

a)和b)应该导致相同的查询计划(尽管这是特定于db的)。b)对于便携性和可读性优于a)。 c)是一个可怕的想法,这会伤害可读性,如果有什么会导致更差的性能。让我们再也不要谈论它。

有没有更好的方法来做到这一点? b)是标准方法。

b)是标准方法。一般来说,编写最简洁的ANSI SQL将会产生最佳性能,因为它允许查询解析器轻松理解您正在尝试执行的操作。试图用技巧来胜过编译器可能在特定的情况下工作,但并不意味着当基数或数据量发生变化或数据库引擎升级时它仍然可以工作。所以,避免这样做,除非你绝对被迫。

+0

+1良好的指导!我肯定也会选择b)! – 2011-12-22 15:41:47

+0

感谢您的回答! – RoyM 2011-12-29 21:11:46