将子查询转换为 JSON 性能

Posted

技术标签:

【中文标题】将子查询转换为 JSON 性能【英文标题】:Convert subquery to JSON performance 【发布时间】:2022-01-23 21:52:08 【问题描述】:

我有以下查询,该查询有效,但运行时间超过 30 分钟。最初的外部查询拉回大约 1400 行,然后子查询在某些情况下拉回 100 奇数行。

;WITH products AS (
  SELECT
    PromotionID,
    ProductColourID,
    ProductCode
  FROM dbo.PromotionProducts
)
SELECT
  P.ID,
  P.Code,
  P.Name,
  P.EndDateTime,
  prods = (
    SELECT
      pp.productColourId,
      pp.ProductCode
    FROM products
    FOR JSON PATH
  )
FROM dbo.Promotion P
JOIN products PP ON P.ID = PP.PromotionID
WHERE P.EndDateTime > GETDATE() 

有什么办法可以加快速度吗?

【问题讨论】:

子查询不相关,因此对于外部查询的每一行,它将拉入整个表。然后你在外部查询中再次加入它,这是为了什么? 【参考方案1】:

您的查询看起来不正确,因为子查询与外部查询不相关(因此您将获得每个外部行上的整个表),并且 products 不必要地第二次加入。

相反,只需执行单个相关子查询:

SELECT
  P.ID,
  P.Code,
  P.Name,
  P.EndDateTime,
  prods = (
    SELECT
      pp.productColourId,
      pp.ProductCode
    FROM dbo.PromotionProducts PP
    WHERE P.ID = PP.PromotionID
    FOR JSON PATH
  )
FROM dbo.Promotion P
WHERE P.EndDateTime > GETDATE();

为了使其高效,您可能需要以下索引

Promotion (EndDateTime) INCLUDE (ID, Code, Name)
PromotionProducts (PromotionID) INCLUDE (productColourId, ProductCode)

【讨论】:

非常感谢,效果很好。我不需要索引,因为此查询将运行一次以将数据填充到 dyanmodb 表中。

以上是关于将子查询转换为 JSON 性能的主要内容,如果未能解决你的问题,请参考以下文章

将子查询转换为单个查询 Hive

将子选择 sql 查询转换为 laravel 查询

帮助将子查询转换为带连接的查询

带有子查询的 Oracle 更新 - 性能问题

postgres 将子字符串转换为纪元

将子查询(不在)重写为加入