复合主键上的慢连接

Posted

技术标签:

【中文标题】复合主键上的慢连接【英文标题】:Slow Join on Composite Primary Key 【发布时间】:2017-02-08 12:09:12 【问题描述】:

我有以下查询,它的运行时间约为 2 秒,直到我在 StoreID 上加入 ProductStores,这将其增加到 ~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 ProductStores: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 的哈希匹配(内部连接),我认为这是问题所在,但我不确定如何解释这个?

非常感谢任何帮助!

【问题讨论】:

我不相信你真的有ProductStores上的索引。 执行SELECT * FROM sys.indexes ... 显示它有PX_dbo.ProductStores CLUSTEREDIX_ProductID NONCLUSTEREDIX_StoreID NONCLUSTERED 可以发一下执行计划吗?您是否还在优化顾问中运行了该查询?临时表中有什么? 我已将它们添加为图片,不确定首选格式是什么。我没有,我会调查一下谢谢。 “估计行数”与“实际行数”大不相同。我认为您需要更新表格的统计信息 【参考方案1】:

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 秒,这对于此目的是可以接受的!

【讨论】:

以上是关于复合主键上的慢连接的主要内容,如果未能解决你的问题,请参考以下文章

同一主键上的EF多个外键关系

复合主键?还是具有唯一复合索引的自动增量主键? [关闭]

jpa 复合主键并可与唯一键连接

Bigtable 和复合主键

在查询中的复合外键/主键列上连接表

复合主键:好还是坏?