次のクエリのパフォーマンスを改善しようとしています。
UPDATE [#TempTable]
SET Received = r.Number
FROM [#TempTable]
INNER JOIN (SELECT AgentID,
RuleID,
COUNT(DISTINCT (GroupId)) Number
FROM [#TempTable]
WHERE Passed = 1
GROUP BY AgentID,
RuleID
) r ON r.RuleID = [#TempTable].RuleID AND
r.AgentID = [#TempTable].AgentID
現在、私のテストデータでは約1分かかります。このクエリが存在するすべてのストアドプロシージャに対する変更への入力は限られていますが、おそらくこの1つのクエリを変更することができます。または、インデックスを追加します。次のインデックスを追加してみました。
CREATE CLUSTERED INDEX ix_test ON #TempTable(AgentID, RuleId, GroupId, Passed)
また、実際にクエリにかかる時間は2倍になりました。NON-CLUSTEREDインデックスでも同じ効果が得られます。
効果なしで次のように書き直してみました。
WITH r AS (SELECT AgentID,
RuleID,
COUNT(DISTINCT (GroupId)) Number
FROM [#TempTable]
WHERE Passed = 1
GROUP BY AgentID,
RuleID
)
UPDATE [#TempTable]
SET Received = r.Number
FROM [#TempTable]
INNER JOIN r
ON r.RuleID = [#TempTable].RuleID AND
r.AgentID = [#TempTable].AgentID
次に、このようなウィンドウ関数を使用しようとしました。
UPDATE [#TempTable]
SET Received = COUNT(DISTINCT (CASE WHEN Passed=1 THEN GroupId ELSE NULL END))
OVER (PARTITION BY AgentId, RuleId)
FROM [#TempTable]
この時点で、エラーが発生し始めました
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near 'distinct'.
そこで、2つの質問があります。最初に、OVER句でCOUNT DISTINCTを実行できませんか、それとも間違って記述しましたか?第二に、私がまだ試したことがない改善を提案できる人はいますか?参考までに、これはSQL Server 2008 R2 Enterpriseインスタンスです。
編集:元の実行計画へのリンクを次に示します。私の大きな問題は、このクエリが30〜50回実行されていることです。
https://onedrive.live.com/redir?resid=4C359AF42063BD98%21772
EDIT2:これは、コメントで要求されたとおりにステートメントが存在する完全なループです。私は、ループの目的に関して定期的にこれを扱っている人に確認しています。
DECLARE @Counting INT
SELECT @Counting = 1
-- BEGIN: Cascading Rule check --
WHILE @Counting <= 30
BEGIN
UPDATE w1
SET Passed = 1
FROM [#TempTable] w1,
[#TempTable] w3
WHERE w3.AgentID = w1.AgentID AND
w3.RuleID = w1.CascadeRuleID AND
w3.RulePassed = 1 AND
w1.Passed = 0 AND
w1.NotFlag = 0
UPDATE w1
SET Passed = 1
FROM [#TempTable] w1,
[#TempTable] w3
WHERE w3.AgentID = w1.AgentID AND
w3.RuleID = w1.CascadeRuleID AND
w3.RulePassed = 0 AND
w1.Passed = 0 AND
w1.NotFlag = 1
UPDATE [#TempTable]
SET Received = r.Number
FROM [#TempTable]
INNER JOIN (SELECT AgentID,
RuleID,
COUNT(DISTINCT (GroupID)) Number
FROM [#TempTable]
WHERE Passed = 1
GROUP BY AgentID,
RuleID
) r ON r.RuleID = [#TempTable].RuleID AND
r.AgentID = [#TempTable].AgentID
UPDATE [#TempTable]
SET RulePassed = 1
WHERE TotalNeeded = Received
SELECT @Counting = @Counting + 1
END
count
、列がNULL可能かどうかとは異なります。それはあなたが1減算する必要がある任意のヌルが含まれている場合