Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

गतिरोध पैदा करने वाले प्रश्नों को अद्यतन और सम्मिलित करें

कर्सर से बचें, उस क्वेरी की उन्हें कोई आवश्यकता नहीं थी। 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 ) यह सुनिश्चित करने के लिए कि सम्मिलित पंक्ति अद्यतन विधेय में नहीं आती है; संभावना है कि यह गतिरोध को पूरी तरह से रोक देगा।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक वर्ण स्ट्रिंग से अद्वितीय पहचानकर्ता में कनवर्ट करते समय रूपांतरण विफल रहा

  2. SQL सर्वर (T-SQL) में समय मान में AM/PM कैसे जोड़ें

  3. डेटाबेस + विंडोज प्रमाणीकरण + उपयोगकर्ता नाम/पासवर्ड?

  4. SQL सर्वर में SHOWPLAN_XML कैसे काम करता है

  5. WHERE क्लॉज में शर्त के साथ LEFT JOIN क्यों और कब ON में समान LEFT JOIN के बराबर नहीं है?