慢速加入复合主键

时间:2017-02-08 12:09:12

标签: sql sql-server performance query-optimization

我有以下查询,它的运行时间约为2秒,直到我在ProductStores加入StoreID,这会将其增加到~3分钟,仅加入ProductID会使其保持在~2秒。

SELECT
    Enabled = pp.PspEnabled
    , StockStatusID = ss.ID
    , WebSellable = pp.PspWebSellable
    , CSSellable = pp.PspCsSellable
FROM 
    #ExternalProducts pp 
JOIN 
    Product p ON p.ExternalCode = pp.code
JOIN 
    Stores s ON s.Name = pp.p_externalStore
JOIN 
    StockStatus ss ON ss.Name = pp.PspStockStatus
JOIN 
    ProductStores ps ON (/* Store join increases time only */ ps.StoreID = s.ID AND ps.ProductID = p.ID)

  • 商店:108
  • 产品:136'598
  • 产品商店:609'963

CONSTRAINT [PK_dbo.Stores] 
    PRIMARY KEY CLUSTERED ([ID] ASC)
CONSTRAINT [PK_dbo.Product] 
    PRIMARY KEY CLUSTERED ([ID] ASC)   
CONSTRAINT [PK_dbo.ProductStores] 
    PRIMARY KEY CLUSTERED ([ProductID] ASC, [StoreID] ASC)

CONSTRAINT [FK_dbo.ProductStores_dbo.Stores_SiteID] 
    FOREIGN KEY([StoreID]) REFERENCES [dbo].[Stores] ([ID])
CONSTRAINT [FK_dbo.ProductStores_dbo.Product_ProductID] 
    FOREIGN KEY([ProductID]) REFERENCES [dbo].[Product] ([ID])

执行计划

执行计划显示批量成本来自哈希匹配(内部联接)与哈希密钥探测[dbo].[Stores].Name和哈希密钥构建[#ExternalProducts].p_externalstore我认为这是问题,但我不是确定如何解释这个?

execution plan 1

execution plan 2

hash join

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

Denis Rubashkin指出估计的和实际的行数实际上是非常不同的。在UPDATE STATISTICS无法修改执行计划后,我重新组织了查询以从ProductStores拉出并从#ExternalProducts过滤而不是允许我强制嵌套循环连接(我认为这是更可取的)在较小的结果集上)。

SELECT
    Enabled = pp.PspEnabled
    , StockStatusID = ss.ID
    , WebSellable = pp.PspWebSellable
    , CSSellable = pp.PspCsSellable
FROM ProductStores ps
JOIN Product p ON p.ID = ps.ProductID
JOIN Stores s ON s.ID = ps.StoreID
INNER LOOP JOIN #ExternalProducts pp ON (p.Code = pp.Code AND s.Name = pp.p_externalstore)
JOIN StockStatus ss ON ss.Name = pp.PspStockStatus

这将查询时间从~3分钟缩短到约7秒,这是可以接受的!