कर्सर से बचें, उस क्वेरी की उन्हें कोई आवश्यकता नहीं थी। SQL नहीं है एक अनिवार्य भाषा (यही कारण है कि इसका नाम खराब हो जाता है क्योंकि हर कोई इसे एक के रूप में उपयोग करता है ) - यह एक निर्धारित भाषा है।
पहली चीज जो आप कर सकते हैं वह है अपने एसक्यूएल के मूल निष्पादन को तेज करना, क्वेरी को पार्स करने/निष्पादित करने में कम समय का मतलब गतिरोध की कम संभावना है:
- अपनी सभी तालिकाओं को
[dbo]
with के साथ उपसर्ग करें - यह पार्स चरण में 30% तक की कटौती करता है। - आपकी टेबल के अलावा - यह योजना के चरण से एक छोटी राशि काट देता है।
- उद्धरण पहचानकर्ता हो सकता है चीजों को गति दें।
- ये पूर्व-एसक्यूएल-पीएम के सुझाव हैं, इससे पहले कि कोई इस पर विवाद करने का फैसला करे।
आप डेटा को अपडेट करने के लिए सीटीई का उपयोग कर सकते हैं और फिर UPDATE ... FROM ... SELECT
का उपयोग कर सकते हैं। वास्तविक अद्यतन करने के लिए कथन। यह कर्सर से तेज़ होगा, क्योंकि कर्सर कुत्ते धीमे हैं जब क्लीन सेट ऑपरेशंस (यहां तक कि आपके जैसे सबसे तेज 'फायर होज' कर्सर) की तुलना में। अद्यतन करने में कम समय व्यतीत करने का अर्थ है गतिरोध की संभावना कम। नोट:मेरे पास आपकी मूल तालिका नहीं है, मैं इसे सत्यापित नहीं कर सकता - इसलिए इसे विकास डीबी के विरुद्ध जांचें।
DECLARE @nowTime datetime = convert(datetime, @now, 21);
WITH [DailyAggregates] AS
(
SELECT
[D].[dailyId] AS [dailyId],
[D].[spentDaily] AS [spentDaily],
[D].[impressionsCountCache] AS [impressionsCountCache],
SUM([I].[amountCharged]) as [sumCharged],
COUNT([I].[impressionId]) as [countImpressions]
FROM [dbo].[Daily] AS [D]
INNER JOIN [dbo].[Impressions] AS [I]
ON [I].[dailyId] = [D].[dailyId]
WHERE [I].[isCharged] = 0
AND [I].[showTime] < @nowTime
AND [D].[isActive] = 1
GROUP BY [D].[dailyId], [D].[spentDaily], [D].[impressionsCountCache]
)
UPDATE [dbo].[Daily]
SET [spentDaily] = [A].[spentDaily] + [A].[sumCharged],
[impressionsCountCache] = [A].[impressonsCountCache] + [A].[countImpressions]
FROM [Daily] AS [D]
INNER JOIN [DailyAggregates] AS [A]
ON [D].[dailyId] = [A].[dailyId];
UPDATE [dbo].[Impressions]
SET [isCharged] = 1
WHERE [showTime] < @nowTime
AND [isCharged] = 0;
इसके अलावा आप अपनी अनुक्रमणिका पर पेज लॉक को अस्वीकार कर सकते हैं, इससे कुछ पंक्तियों के पूरे पृष्ठ को लॉक करने की संभावना कम हो जाएगी (लॉकिंग एस्केलेशन के कारण, पूरे पेज को लॉक होने से पहले केवल कुछ निश्चित पंक्तियों को लॉक करने की आवश्यकता होती है)।पी>
CREATE NONCLUSTERED INDEX [IDX_Impressions_isCharged_showTime] ON [dbo].[Impressions]
(
[showTime] ASC, -- I have a hunch that switching these around might have an effect.
[isCharged] ASC
)
WITH (ALLOW_PAGE_LOCKS = OFF)
ON [PRIMARY]
GO
यह सिर्फ गतिरोध की संभावना को कम करेगा। आप पहले किसी दिनांक को @now को प्रतिबंधित करने का प्रयास कर सकते हैं (अर्थात today - 1 day
) यह सुनिश्चित करने के लिए कि सम्मिलित पंक्ति अद्यतन विधेय में नहीं आती है; संभावना है कि यह गतिरोध को पूरी तरह से रोक देगा।