使用 SQL Server 2008。
我有多个位置,每个位置都包含多个部门,每个部门都包含多个项目,这些项目可以有零到多个扫描。每个扫描都与一个特定的操作相关,该操作可能有也可能没有截止时间。每个项目还属于属于特定作业的特定包。每个作业包含一个或多个包含一个或多个项目的包。
+=============+ +=============+
| Locations | | Jobs |
+=============+ +=============+
^ ^
| |
+=============+ +=============+ +=============+
| Departments | <-- | Items | --> | Packages |
+=============+ +=============+ +=============+
^
|
+=============+ +=============+
| Scans | --> | Operations |
+=============+ +=============+
我试图做的是获取按位置和扫描日期分组的作业的扫描计数。棘手的部分是我只想按每个项目的日期/时间计算第一次扫描,其中操作的截止时间不为空。(注意:扫描肯定不会按表中的日期/时间顺序排列。)
我的查询让我得到了正确的结果,但是当 Job 的 Items 数量达到 75,000 左右时,它的速度非常慢。我正在推动一个新的服务器——我知道我们的硬件缺乏——但我想知道我在查询中是否有什么事情也让它陷入困境。
从我可以从执行计划中收集到的信息来看,查询的大部分成本似乎都在子查询中,以查找每个项目的第一次扫描。它对操作表索引(ID,Cutoff)进行索引扫描(0%),然后是惰性假脱机(19%)。它对 Scans 表索引(ItemID、DateTime、OperationID、ID)进行索引查找 (61%)。随后的嵌套循环(内连接)只有 2%,Top 运算符为 0%。(并不是说我真的很了解我刚刚输入的内容,但我正在努力提供尽可能多的信息......)
这是查询:
SELECT
Departments.LocationID
, DATEADD(dd, 0, DATEDIFF(dd, 0, Scans.DateTime))
, COUNT(Scans.ItemID) AS [COUNT]
FROM
Items
INNER JOIN Scans
ON Scans.ID =
(
SELECT TOP 1
Scans.ID
FROM
Scans
INNER JOIN Operations
ON Scans.OperationID = Operations.ID
WHERE
Operations.Cutoff IS NOT NULL
AND Scans.ItemID = Items.ID
ORDER BY
Scans.DateTime
)
INNER JOIN Operations
ON Scans.OperationID = Operations.ID
INNER JOIN Packages
ON Items.PackageID = Packages.ID
INNER JOIN Departments
ON Items.DepartmentID = Departments.ID
WHERE
Packages.JobID = @ID
GROUP BY
Departments.LocationID
, DATEADD(dd, 0, DATEDIFF(dd, 0, Scans.DateTime));
这将返回一个结果样本,如下所示:
8 2012-06-08 00:00:00.000 11842
21 2012-06-07 00:00:00.000 502
11 2012-06-12 00:00:00.000 1841
15 2012-06-11 00:00:00.000 4314
16 2012-06-09 00:00:00.000 278
23 2012-06-12 00:00:00.000 1345
6 2012-06-06 00:00:00.000 2005
20 2012-06-08 00:00:00.000 352
14 2012-06-07 00:00:00.000 2408
8 2012-06-11 00:00:00.000 290
19 2012-06-10 00:00:00.000 85
20 2012-06-11 00:00:00.000 5484
7 2012-06-10 00:00:00.000 2389
16 2012-06-06 00:00:00.000 6762
18 2012-06-09 00:00:00.000 4473
14 2012-06-10 00:00:00.000 2364
1 2012-06-11 00:00:00.000 1531
22 2012-06-08 00:00:00.000 14534
5 2012-06-10 00:00:00.000 11908
9 2012-06-12 00:00:00.000 47
19 2012-06-07 00:00:00.000 559
7 2012-06-07 00:00:00.000 2576
这是执行计划(不确定自原始帖子以来我进行了哪些更改,但成本百分比略有不同。瓶颈似乎仍然在同一区域):