子テーブル内の各タイプのコミュニケの総数を計算し、親テーブルを更新するためのポストプロセスとしてストアドプロシージャがトリガーされるソリューションを継承しました。
親への子行の数が2〜3000を超えると、クエリが最適化されず、タイムアウトが発生します。
これは、5つの異なるクエリではなく、1つのクエリに各通信タイプをグループ化することで解決できるように感じます。
私はこの擬似コードのようなものを考えています:
UPDATE Parent SET Total = query.Total, email = query.email, letter = query.letter, spoken = query.spoken, written = query.written
JOIN ... as query
WHERE Parent.ParentID = @pid
私の腸は正しいと感じていますか、それともSQL Serverはこれを内部的に最適化できますか?
インデックスを追加することはオプションかもしれませんが、サブクエリのそれぞれは、私が1つをヒットするのを見ることができる限りです。
ストアドプロシージャは次のようになります。
CREATE PROCEDURE [dbo].[UpdateParentTotal]
@pid int
AS
UPDATE Parent
-- count Total
set Total = (select count(*) from Child
where Child.ParentID = Parent.ParentID),
-- count Type "email" total
email = (select count(*) from Child
where Child.ParentID = Parent.ParentID and Type = 1),
-- count Type "letter" total
letter = (select count(*) from Child
where Child.ParentID = Parent.ParentID and Type = 2),
-- count Total for Spoken word
spoken = (select count(*) from Child
where Child.ParentID = Parent.ParentID and Type > 99),
-- count all types of written word
written = (select count(*) from Child
where Child.ParentID = Parent.ParentID and ((Type > 1 and Type < 100) or Type is null))
where ParentID = @pid
GO
PS。どのような解決策が必要か正確にはわからないため、質問に名前を付けるのは非常に困難でした。
あなたはあなたの考え方が正しいです...あなたはこれらの計算のすべてを単一のクエリに入れて、それに接続することができます。例については、以下を参照してください。
UPDATE Parent
SET
Total = CountTotal,
Email = CountEmail
Letter = CountLetter
Spoken = CountSpoken
Written = CountWritten
FROM
Parent
INNER JOIN
(
SELECT
ParentID,
COUNT(*) CountTotal,
COUNT(CASE WHEN [Type] = 1 THEN 1 END) AS CountEmail,
COUNT(CASE WHEN [Type] = 2 THEN 1 END) AS CountLetter,
COUNT(CASE WHEN [Type] >99 THEN 1 END) AS CountSpoken,
COUNT(CASE WHEN (([Type] > 1 and [Type] < 100) or [Type] is null)) THEN 1 END) AS CountWritten,
FROM Child
GROUP BY ParentID
) Child ON
Parent.ParentID = Child.ParentID
WHERE Parent.ParentID = @pid
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加