Aşağıdaki sorgunun performansını artırmaya çalışıyorum:
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
Şu anda test verilerim ile yaklaşık bir dakika sürer. Bu sorgunun bulunduğu tüm saklı yordamda değişiklik yapma konusunda sınırlı miktarda girdi var, ancak büyük olasılıkla bu sorguyu değiştirmelerini sağlayabilirim. Veya bir dizin ekleyin. Aşağıdaki dizini eklemeye çalıştım:
CREATE CLUSTERED INDEX ix_test ON #TempTable(AgentID, RuleId, GroupId, Passed)
Ve aslında sorgunun harcadığı zamanı iki katına çıkardı. Aynı etkiyi CLUSTERED endeksiyle elde ediyorum.
Etkisi olmayan şekilde tekrar yazmaya çalıştım.
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
Sonra böyle bir pencere işlevi kullanmaya çalıştım.
UPDATE [#TempTable]
SET Received = COUNT(DISTINCT (CASE WHEN Passed=1 THEN GroupId ELSE NULL END))
OVER (PARTITION BY AgentId, RuleId)
FROM [#TempTable]
Bu noktada hatayı almaya başladım
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near 'distinct'.
Bu yüzden iki sorum var. Öncelikle, OVER yan tümcesinde COUNT DISTINCT yapamazsınız veya yanlış mı yazdım? İkincisi, daha önce denemediğim bir gelişme önerebilir mi? FYI bu bir SQL Server 2008 R2 Enterprise örneğidir.
EDIT: İşte orijinal uygulama planına bir link. Ayrıca benim büyük sorunumun bu sorgunun 30-50 kez çalıştırılması olduğunu da belirtmeliyim.
https://onedrive.live.com/redir?resid=4C359AF42063BD98%21772
EDIT2: İşte açıklamalarda istendiği gibi ifadenin tam döngüsü. Döngü amacına göre bununla düzenli olarak çalışan kişiyi kontrol ediyorum.
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
, sütun null değerindeyse aynı değildir . Herhangi bir boş değer içeriyorsa, 1'i çıkarmanız gerekir.