2011-06-17 68 views
1

我有一个名为性能比较:全外连接VS联盟,联盟所有

mktActualsales (SaleID, EmployeeID, PeriodID,PositionID) 
mktActualSalesItems(SaleItemID, saleID, Item, Quantity) 
mktSalesTargets(TargetID, EmployeeID, PeriodID,PositionID) 
mktSalesTargetItems(TargetITemID, TargetID,ItemID, Quantity) 
sysPeriods(PeriodID, StartDate, EndDate) 

的关系是上面的表格中销售明显和saleDetails通过SaleID和目标以及相关TargetDetail通过目标ID的相关表。我想要展示的是员工销售额和各个时期的目标。有些时候销售缺失,在其他时期可能缺少目标。我做这个计划(到目前为止)是采取销售和销售的内部连接在一个子查询中,目标和targetDetail在另一个子查询中,然后在这两个子查询中完全外连接为我提供我需要的数据。但结果非常缓慢。我能做些什么来加速表现。我已经搜索了性能比较黑/白完全外连接和工会,但没有找到任何运气。在现阶段,我不知道,如果结果我想可以用联盟/联盟所有

编辑
这是我迄今为止的查询中来达到的。编辑表格以及

SELECT sale.ActualSaleID, 
     COALESCE (sale.EmployeeID, saleTarget.EmployeeID) AS EmployeeID, 
     COALESCE (sale.PositionID, saleTarget.PositionID) AS PositionID, 
     COALESCE (sale.PeriodID, saleTarget.PeriodID) AS PeriodID, 
     COALESCE (sale.SKUID, saleTarget.SKUID) AS SKUID, 
     COALESCE (sale.SalesQuantity, 0) AS SalesQuantity, 
     saleTarget.SalesTargetID, 
     COALESCE (saleTarget.TargetQuantity, 0) AS TargetQuantity, 
     saleTarget.SalesTargetItemID, 
     sale.ActualSaleItemID, 
     p.StartDate, 
     p.EndDate 
FROM (
     SELECT s.ActualSaleID, 
       s.EmployeeID, 
       s.PeriodID, 
       s.PositionID, 
       si.ActualSaleItemID, 
       si.SKUID, 
       si.SalesQuantity 
     FROM dbo.mktActualSaleItems AS si 
      INNER JOIN dbo.mktActualSales AS s 
       ON si.ActualSaleID = s.ActualSaleID 
    ) AS sale 
    FULL OUTER JOIN 
    (
     SELECT t.EmployeeID, 
       t.PeriodID, 
       t.PositionID, 
       t.SalesTargetID, 
       ti.SKUID, 
       ti.TargetQuantity, 
       ti.SalesTargetItemID 
     FROM dbo.mktSalesTargetItems AS ti 
      INNER JOIN dbo.mktSalesTargets AS t 
       ON t.SalesTargetID = ti.SalesTargetID 
    ) AS saleTarget 
     ON sale.PeriodID = saleTarget.PeriodID 
     AND sale.PositionID = saleTarget.PositionID 
     AND sale.SKUID = saleTarget.SKUID 
    INNER JOIN dbo.sysPeriods AS p 
     ON p.PeriodID = COALESCE (sale.PeriodID, saleTarget.PeriodID) 

问候

+0

这两个子查询都是在PeriodID和EmployeeID – 2011-06-17 07:35:51

+0

上外部连接的吗?您可以给我们提供您迄今为止的查询以及您想要实现的一些示例吗?我不完全明白你想要的结果是什么。 – 2011-06-17 07:39:12

+0

@Oliver Hanappi编辑了这个问题 – 2011-06-17 07:58:44

回答

1

我不认为你需要的子查询,你可以做同样的事情在一个查询

SELECT s.ActualSaleID, 
     COALESCE (s.EmployeeID, t.EmployeeID) AS EmployeeID, 
     COALESCE (s.PositionID, t.PositionID) AS PositionID, 
     COALESCE (s.PeriodID, t.PeriodID) AS PeriodID, 
     COALESCE (si.SKUID, ti.SKUID) AS SKUID, 
     COALESCE (si.Quantity, 0) AS SalesQuantity, 
     t.TargetID, 
     COALESCE (ti.Quantity, 0) AS TargetQuantity, 
     ti.TargetITemID, 
     si.SaleItemID, 
     p.StartDate, 
     p.EndDate 
FROM dbo.mktActualSales AS s 
     INNER JOIN dbo.mktActualSaleItems AS si 
      ON si.ActualSaleID = s.ActualSaleID 
    FULL OUTER JOIN dbo.mktSalesTargets AS t 
     ON s.PeriodID = t.PeriodID 
     AND s.PositionID = t.PositionID 
     AND si.SKUID = ti.SKUID 
      INNER JOIN dbo.mktSalesTargetItems AS ti 
       ON t.SalesTargetID = ti.SalesTargetID 
    INNER JOIN dbo.sysPeriods AS p 
     ON p.PeriodID = COALESCE (s.PeriodID, t.PeriodID) 

我不知道关于命名字段,但你明白了。

这可能会加快查询速度。

不要忘记检查索引!

+0

把它们放在子查询中让我很容易理解。会不会子查询增加性能呢? – 2011-06-17 09:21:23

+0

嗯,这取决于你的dbms可以足够聪明地与你的查询做适当的连接,但它可能不是。你不要让他有机会通过给他提供子查询来选择最佳计划,而在一个查询中,你让dbms选择最佳计划。最好的方法是运行查询...或查看执行计划! – 2011-06-17 09:22:59

+0

PeriodID和PositionID出现在mktActualSales和mktSalesTargets中,其中SKUID出现在mktSaleTargetItems和mktAcutalSaleItems中。你能否相应地更新这个查询 – 2011-06-17 10:15:23

1

我认为你在查询中有一个错误 - 你在SALE和SALETARGET之间的连接不包括employeeID列。但是我认为你得到的行比你需要的要多得多......

但是,加快查询速度的方法是找出为什么他们放慢速度的原因;执行计划是要走的路。使用查询分析器来告诉你发生了什么 - 你是否碰到所有联接的索引?如果您已经用尽了当前实现的所有选项,则只需重写查询即可使用union语句。

作为一种风格,我认为应该不需要在您加入的列上使用COALESCE - 它们永远不会是空的,它往往会隐藏错误。

+0

EmployeeID与指定ID有一对一的关系,我在这里只有一点反规范化,它不会给出不正确的结果。由于我正在进行完全外部联接,所以很有可能一个表中的列可能为空 – 2011-06-17 09:24:26

+0

我在查询中根本看不到指定标识 - 您将在列周期,位置和skuid上加入SALE和SALETARGET。因此,您将获得一个交叉连接 - 销售和saletarget中的每个员工都有一个记录。这是不正确的?你可以尝试运行查询返回两个sale.EmployeeID和saleTarget.EmployeeID检查? – 2011-06-17 10:11:27

+0

@Veville我的意思是PositionID – 2011-06-17 10:22:27