使用自联接优化SQL视图/查询

时间:2012-11-30 22:37:43

标签: sql sql-server-2005

我是一个运行SQL SERVER 2005的极端新手。我有两个表,我在一个视图中放在一起。第一个表只有2列进入视图。一列是ID号,另一列是名称。第二个表是所有数据的位置。该表中的列是ID,Date,Hour,PriceType,MarketType和Price。我的目标是有一个视图,将PriceType过滤为固定值,然后在MarketType为DAM时从MarketType为RTM的价格中获取Price。现在看起来像以下....

SELECT dbo.nodes.commonname,
       dbo.nodes.node_id,
       da.pricedate,
       da.hour,
       rt.price            AS rtm,
       da.price            AS dam,
       da.price - rt.price AS dart
FROM   dbo.pnodes
       INNER JOIN dbo.pnode_prices AS da
               ON dbo.pnodes.node_id = da.pnode_id
       INNER JOIN dbo.pnode_prices AS rt
               ON dbo.pnodes.node_id = rt.pnode_id
                  AND da.pricetype = rt.pricetype
                  AND da.pricedate = rt.pricedate
                  AND da.hour = rt.hour
WHERE  ( da.pricetype = 'LMP' )
       AND ( da.markettype = 'DAM' )
       AND ( rt.markettype = 'RTM' ) 

这种观点本身并不需要这么长时间。有时我想采取另一个步骤,并在两个视图之间有所不同,我将运行一个连接上述视图的查询,并获得Price where view1.CommonName=abc and view2.CommonName=xyz的差异。当我运行该查询时,运行所需的时间是运行简单视图所需的10倍。我假设如果我做得最好,那就不会花费10倍的时间。为了改善这种情况,我能做些什么低成果?

1 个答案:

答案 0 :(得分:1)

总的来说,您的查询看起来没问题,但作为一个视图运行,显然对您来说效果不佳。也就是说,我想对查询进行一些轻微的重构。将WHERE条件移动到JOIN组件中。

确保您在节点表上的CommonName上有一个索引,您将对其应用过滤器。在price_nodes表上,有一个复合索引(node_id,markettype,pricetype)。

SELECT 
      N.commonname,
      N.node_id,
      da.pricedate,
      da.hour,
      rt.price            AS rtm,
      da.price            AS dam,
      da.price - rt.price AS dart
   FROM
      dbo.pnodes N

         INNER JOIN dbo.pnode_prices AS da
               ON N.node_id = da.pnode_id
              AND da.markettype = 'DAM'
              AND da.pricetype = 'LMP'

            INNER JOIN dbo.pnode_prices AS rt
               ON da.node_id = rt.pnode_id
              AND rt.markettype = 'RTM'
              AND da.pricetype = rt.pricetype
              AND da.pricedate = rt.pricedate
              AND da.hour = rt.hour

这样,where子句可以完全依赖于公司A对B的条件。其余的连接基于它们的“node_id”。由于node_id已经从pNodes到da.node_id,我还将连接从“da”连接到“rt”,因此使用da.Node_id到rt.node_id。这可能是引擎陷入困境的一件事。