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

जाँच कर रहा है कि क्या गैर-LOB कॉलम को अद्यतन करने की आवश्यकता है

कभी-कभी मैं देखता हूं कि लोग किसी विशेष कॉलम में समान मान लिखने से बचने के लिए अपने अपडेट स्टेटमेंट को "ऑप्टिमाइज़" करने का प्रयास करते हैं। मेरी समझ हमेशा यह रही है कि यदि आप एक पंक्ति को अद्यतन करने जा रहे हैं, यह मानते हुए कि सभी मान पंक्ति में हैं, तो पंक्ति को लॉक करने की लागत उस पंक्ति में एक, दो या सभी स्तंभों को अद्यतन करने की वृद्धिशील लागत से बहुत अधिक है। .

इसलिए, मैंने इसका परीक्षण करने के लिए एक साधारण तालिका बनाई:

टेबल डीबीओ बनाएं। जो कुछ भी (आईडी पहचान पहचान (1,1) प्राथमिक कुंजी, v1 NVARCHAR (50) शून्य नहीं, v2 NVARCHAR (50) शून्य नहीं, v3 NVARCHAR (50) शून्य नहीं, v4 NVARCHAR (50) नहीं NULL, v5 NVARCHAR(50) NOT NULL, v6 NVARCHAR(50) NOT NULL);

फिर मैंने विभिन्न प्रकार के छोटे तारों के साथ 50,000 पंक्तियों वाली तालिका को पॉप्युलेट करने के लिए एक संग्रहीत कार्यविधि बनाई:

क्रिएट प्रोसीजर dbo.cleanASBEGIN SET NOCOUNT ON; ट्रंकेट टेबल डीबीओ। जो भी हो;; एक्स (डी) एएस के साथ (मूल्यों (एन'एबीसी'), (एन'डीईएफ'), (एन'घी'), (एन'जेकेएल'), (एन'एमनो'), (एन से डी चुनें।" 'pqr')) AS y(d) ) INSERT dbo.whatever(v1, v2, v3, v4, v5, v6) सेलेक्ट टॉप (50000) x1.d, x2.d, x3.d, x4.d, x5 .d, x6.d से x AS x1, x AS x2, x AS x3, x AS x4, x AS x5, x AS x6, x AS x7;ENDGO

फिर मैंने दो तरह से तैयार किए गए अपडेट स्टेटमेंट लिखे, जिन्हें आप इस वैरिएबल असाइनमेंट को देखते हुए एक विशिष्ट कॉलम पर लिखने से "बच" सकते हैं:

घोषणा @v1 NVARCHAR(50) =N'abc', @v2 NVARCHAR(50) =N'def', @v3 NVARCHAR(50) =N'ghi', @v4 NVARCHAR(50) =N'jkl ', @v5 NVARCHAR(50) =N'mno', @v6 NVARCHAR(50) =N'pqr';

सबसे पहले CASE एक्सप्रेशन का उपयोग करके यह जाँचने के लिए कि क्या कॉलम में मान वैरिएबल के मान के समान है:

अद्यतन dbo.जो भी सेट v1 =मामला जब v1 <> @v1 ​​तब @v1 ELSE v1 END, v2 =मामला जब v2 <> @v2 तब @v2 ELSE v2 END, v3 =केस जब v3 <> @v3 तब @v3 ELSE v3 END, v4 =केस जब v4 <> @v4 तब @v4 ELSE v4 END, v5 =केस जब v5 <> @v5 तब @v5 ELSE v5 END, v6 =केस जब v6 <> @v6 तब @v6 ELSE v6 अंत में (v1 <> @v1 ​​या v2 <> @v2 या v3 <> @v3 या v4 <> @v4 या v5 <> @v5 या v6 <> @v6);

और दूसरा प्रत्येक कॉलम के लिए एक स्वतंत्र अद्यतन जारी करके (प्रत्येक केवल उन पंक्तियों को लक्षित करता है जहां वह मान वास्तव में बदल गया था):

अद्यतन dbo.जो भी SET v1 =@v1 जहां v1 <> @v1; अद्यतन dbo.;अद्यतन dbo. /पूर्व> 

फिर मैं इसकी तुलना उस तरीके से करूंगा जिस तरह से हम में से अधिकांश आज करेंगे:बस सभी कॉलम अपडेट करें बिना परवाह किए अगर वह उस विशेष कॉलम के लिए पहले से मौजूद मान था:

अद्यतन dbo। जो भी SET v1 =@v1, v2 =@v2, v3 =@v3, v4 =@v4, v5 =@v5, v6 =@v6WHERE (v1 <> @v1 ​​या v2 <> @v2 या v3 <> @v3 या v4 <> @v4 या v5 <> @v5 या v6 <> @v6);

(ये सभी मानते हैं कि कॉलम और पैरामीटर/चर न्यूलेबल नहीं हैं - अगर ऐसा है तो उन्हें दोनों तरफ NULLs की तुलना करने के लिए COALESCE का उपयोग करने की आवश्यकता होगी। वे यह भी मानते हैं कि आपके पास एक अतिरिक्त WHERE क्लॉज होगा विशिष्ट पंक्तियों को लक्षित करें - इस उदाहरण में आप व्यापक WHERE क्लॉज के बिना पहली और तीसरी क्वेरी चला सकते हैं और लगभग समान परिणाम देख सकते हैं। मैंने इसे संक्षिप्तता के लिए सरल रखा है।)

तब मैं देखना चाहता था कि इन तीन मामलों में क्या होता है जब कोई मूल्य बदला जा सकता है, जब विशेष मूल्यों को बदला जा सकता है, जब कोई मूल्य नहीं बदला जाएगा, और जब सभी मूल्यों को बदल दिया जाएगा। मैं विशेष कॉलम में स्थिरांक डालने के लिए संग्रहीत कार्यविधि को बदलकर, या चर को असाइन करने के तरीके को बदलकर इसे प्रभावित कर सकता था।

-- यह दिखाने के लिए कि किसी पंक्ति में कोई मान कब बदल सकता है, प्रक्रिया पूर्ण क्रॉस जॉइन का उपयोग करती है:SELECT TOP (50000) x1.d, x2.d, x3.d, x4.d, x5.d, x6 .d - यह दिखाने के लिए कि कई पंक्तियों पर विशेष मान कब बदलेंगे, हम स्थिरांक को हार्ड-कोड कर सकते हैं:- दो मान छूट:शीर्ष चुनें (50000) N'abc', N'def', x3.d, x4.d , x5.d, x6.d -- चार मान छूट:दिखाने के लिए TOP (50000) N'abc', N'def', N'ghi', N'jkl', x5.d, x6.d -- चुनें जब कोई मान नहीं बदलेगा, तो हम सभी छह मानों को हार्ड-कोड करते हैं:SELECT TOP (50000) N'abc', N'def', N'ghi', N'jkl', N'mno', N'pqr' -- और यह दिखाने के लिए कि सभी मान कब बदलेंगे, एक भिन्न चर असाइनमेंट होगा:DECLARE @v1 NVARCHAR(50) =N'zzz', @v2 NVARCHAR(50) =N'zzz', @v3 NVARCHAR(50) =N 'zzz', @v4 NVARCHAR(50) =N'zzz', @v5 NVARCHAR(50) =N'zzz', @v6 NVARCHAR(50) =N'zzz';

परिणाम

इन परीक्षणों को चलाने के बाद, हर एक परिदृश्य में "अंधा अद्यतन" जीता। अब, आप सोच रहे हैं, दो सौ मिलीसेकंड क्या है? एक्सट्रपोलेट। यदि आप अपने सिस्टम में बहुत सारे अपडेट कर रहे हैं, तो यह वास्तव में एक टोल लेना शुरू कर सकता है।

प्लान एक्सप्लोरर में विस्तृत परिणाम:कोई भी बदलाव | 2 मान छूट | 4 मान छूट | सभी मान छूट | सभी परिवर्तन

रोजी से मिले फीडबैक के आधार पर, मैंने कुछ इंडेक्स के साथ भी इसका परीक्षण करने का फैसला किया:

dbo पर INDEX X1 बनाएं। जो भी (v1); dbo पर INDEX x2 बनाएं। 

इन अनुक्रमितों के साथ अवधियों में काफी वृद्धि हुई थी:

प्लान एक्सप्लोरर में विस्तृत परिणाम:कोई भी बदलाव | 2 मान छूट | 4 मान छूट | सभी मान छूट | सभी परिवर्तन

निष्कर्ष

इस परीक्षण से, मुझे ऐसा लगता है कि आमतौर पर यह जांचने योग्य नहीं है कि कोई मान अपडेट किया जाना चाहिए या नहीं। यदि आपका अद्यतन विवरण कई स्तंभों को प्रभावित करता है, तो आपके लिए उन सभी स्तंभों को स्कैन करना लगभग हमेशा सस्ता होता है, जहां प्रत्येक स्तंभ को अलग-अलग जांचने के बजाय कोई भी मान बदल गया हो। भविष्य की पोस्ट में, मैं जाँच करूँगा कि क्या यह परिदृश्य LOB कॉलम के लिए समान है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL में डेटाबेस कैसे बनाते हैं?

  2. एक समान क्वेरी के लिए एकाधिक योजनाएं

  3. अपाचे स्पार्क के साथ प्रज्वलित हो जाओ - भाग 1

  4. टी-एसक्यूएल में एक तिथि से महीना कैसे प्राप्त करें

  5. श्रेणियों को प्रबंधित करना और थ्रेड और पोस्ट पर वोटिंग जैसी अधिक उन्नत सुविधाएँ जोड़ना