TSQL:根据孩子的条件选择父母
Posted
技术标签:
【中文标题】TSQL:根据孩子的条件选择父母【英文标题】:TSQL: Selecting parent based on conditions on child 【发布时间】:2021-12-27 05:32:24 【问题描述】:我有一个父表 Orders
和一个子表 Jobs
,其中包含以下示例数据
我想根据以下要求选择订单
1>每个订单可能有 0 个或多个作业。如果订单没有任何工作,请不要选择它。
2>一个用户不能处理多个属于同一订单的工作。
例如,用户 1
无法处理属于订单 1 和 2 的作业,因为他已经处理过同一订单的作业 1
和 4
。
3>只选择在Requested
状态下工作的订单
我有以下查询,它给了我预期的结果
DECLARE @UserID INT = 2
SELECT O.OrderID
FROM Orders O
JOIN Jobs J ON J.OrderID = O.OrderID
WHERE
J.JobStatus = 'Requested' AND
NOT EXISTS
(
--Must not have worked this Order
SELECT 1 FROM Jobs J1
WHERE J1.OrderID = O.OrderID AND J1.UserID = @UserID
)
Group By o.OrderID
SQL Fiddle Demo
查询连接Jobs
表两次。我正在尝试优化查询并寻找一种方法来通过使用Jobs
表在可能的情况下仅使用一次来实现预期结果。任何其他解决方案也值得赞赏。如果需要,我可以更改表架构。
jobs 表有将近 20M 行,并且有时查询显示性能不佳。 (是的,我们查看了索引)。我认为它的扫描作业表两次导致性能问题。
【问题讨论】:
根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或输入到问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。 在询问性能问题时,通常需要执行计划(使用粘贴计划)。 【参考方案1】:如果目标只是“仅使用 Jobs 表一次”,我会尝试类似:
DECLARE @UserID INT = 2
SELECT
O.OrderID
FROM
Orders O
INNER JOIN Jobs J ON J.OrderID = O.OrderID
GROUP BY
O.OrderID
HAVING
SUM(CASE WHEN J.JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN J.UserID = @UserId THEN 1 ELSE 0 END) = 0
SQL Fiddle
为了进一步优化,我建议将JobStatus
列的varchar
数据类型替换为tinyint
之一(并创建一个JobStatuses
表)。一旦您的 Job
表有 20M 条记录,varchar(10)
就会为您提供 190 Mb,但是使用 tinyint
会将列大小减少到 19 Mb — 这可以减少 IO-Read 操作。
我会尝试将子过滤与与父母一起加入过滤分开。这种方法可能会为单个操作使用更少的内存并因此而提高性能:
DECLARE @UserID INT = 2
DECLARE @OrderIDs TABLE (OrderID INT NOT NULL PRIMARY KEY)
INSERT INTO @OrderIDs
SELECT
OrderID
FROM
Jobs
GROUP BY
OrderID
HAVING
SUM(CASE WHEN JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN UserID = @UserId THEN 1 ELSE 0 END) = 0
SELECT
O.*
FROM
Orders O
INNER JOIN @OrderIDs ids on ids.OrderID = O.OrderID
【讨论】:
作业状态实际上是int类型的ID
。只是为了理解目的,我将其保留为 nvarchar
使用这种方法看起来我什至不必加入 Orders 表。我可以直接使用 Jobs 表来获取 OrderID【参考方案2】:
您可以考虑将以下索引添加到Jobs
表中:
CREATE INDEX idx_jobs ON Jobs (OrderID, UserID, JobStatus);
如果使用此索引,则应加快上述查询中不存在的子查询。此外,它还可用于外部***查询中从 Orders
到 Jobs
的连接(尽管 SQL Server 可能必须进行索引扫描)。
【讨论】:
以上是关于TSQL:根据孩子的条件选择父母的主要内容,如果未能解决你的问题,请参考以下文章