SQL Server 2008 を使用しています。
複数の場所があり、それぞれに複数の部門があり、各部門にはゼロから多数のスキャンを持つことができる複数のアイテムが含まれています。各スキャンは、カットオフ タイムがある場合とない場合がある特定の操作に関連しています。各アイテムは、特定のジョブに属する特定のパッケージにも属します。各ジョブには、1 つ以上のアイテムを含む 1 つ以上のパッケージが含まれます。
+=============+ +=============+
| Locations | | Jobs |
+=============+ +=============+
^ ^
| |
+=============+ +=============+ +=============+
| Departments | <-- | Items | --> | Packages |
+=============+ +=============+ +=============+
^
|
+=============+ +=============+
| Scans | --> | Operations |
+=============+ +=============+
私がやろうとしているのは、場所とスキャンの日付でグループ化されたジョブのスキャンの数を取得することです。トリッキーな部分は、操作のカットオフ時間が null ではない項目ごとに、日付/時刻による最初のスキャンのみをカウントしたいということです。(注: スキャンは、テーブル内の日付/時間順ではありません。)
私が持っているクエリは正しい結果を得ていますが、ジョブのアイテム数が 75,000 程度に達すると非常に遅くなります。私は新しいサーバーを求めています -- 私たちのハードウェアが不足していることは知っています -- しかし、私がクエリで行っていることでサーバーが動かなくなっているのではないかと考えています。
実行計画から得られるわずかな情報から、クエリのコストのほとんどは、各アイテムの最初のスキャンを見つけるためのサブクエリにあるようです。Operations テーブルのインデックス (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
実行計画は次のとおりです (元の投稿以降に何を変更したかはわかりませんが、コスト % はわずかに異なります。ただし、ボトルネックはまだ同じ領域にあるようです)。