मुझे पता है कि आप ज्यादातर चिंतित हैं UPDATE प्रदर्शन के बारे और , लेकिन एक साथी "ओआरएम" अनुरक्षक के रूप में, मुझे आपको "परिवर्तित" , "अशक्त" , और "डिफ़ॉल्ट" के बीच अंतर करने की समस्या पर एक और परिप्रेक्ष्य देना चाहिए मानों के , जो हैं एसक्यूएल में तीन अलग-अलग चीजें, लेकिन संभवतः जावा और अधिकांश ओआरएम में केवल एक चीज:
अपने औचित्य का अनुवाद करना INSERTबयानों के
बैटचैबिलिटी और स्टेटमेंट कैचैबिलिटी के पक्ष में आपके तर्क उसी तरह से सही हैं INSERTजैसे कि वे बयान करते हैंUPDATE बयानों के करते हैं। लेकिन INSERTबयानों के मामले में , बयान से एक कॉलम को छोड़ना एक अलग शब्दार्थ है UPDATE। इसे लागू करने का मतलब है DEFAULT। निम्नलिखित दो शब्दार्थ समतुल्य हैं:
INSERT INTO t (a, b) VALUES (1, 2);
INSERT INTO t (a, b, c) VALUES (1, 2, DEFAULT);
यह सच नहीं है UPDATE, जहां पहले दो शब्द समतुल्य हैं, और तीसरे में एक पूरी तरह से अलग अर्थ है:
-- These are the same
UPDATE t SET a = 1, b = 2;
UPDATE t SET a = 1, b = 2, c = c;
-- This is different!
UPDATE t SET a = 1, b = 2, c = DEFAULT;
अधिकांश डेटाबेस क्लाइंट API, जिसमें JDBC और परिणाम, JPA शामिल हैं, एक DEFAULTअभिव्यक्ति को बाइंड चर में बाँधने की अनुमति नहीं देते हैं - ज्यादातर क्योंकि सर्वर इसे भी अनुमति नहीं देते हैं। यदि आप एक ही एसक्यूएल स्टेटमेंट को पूर्वोक्त बैटचैबिलिटी और स्टेटमेंट कैचेबिलिटी कारणों के लिए फिर से उपयोग करना चाहते हैं, तो आप दोनों मामलों में निम्नलिखित स्टेटमेंट का उपयोग करेंगे (मानकर(a, b, c) सभी कॉलम हैं t):
INSERT INTO t (a, b, c) VALUES (?, ?, ?);
और चूंकि cसेट नहीं किया गया है, आप शायद जावा nullको तीसरे बाइंड चर में बाँध देंगे , क्योंकि कई ओआरएम भी NULLऔर DEFAULT( jOOQ) के बीच अंतर नहीं कर सकते हैं , के , उदाहरण के लिए यहाँ एक अपवाद है)। वे केवल जावा देखते हैं nullऔर यह नहीं जानते कि क्या इसका मतलब है NULL(जैसा कि अज्ञात मूल्य में) या DEFAULT(जैसा कि असमान मूल्य में)।
कई मामलों में, यह अंतर कोई मायने नहीं रखता है, लेकिन यदि आपका कॉलम c निम्नलिखित में से किसी भी सुविधा का उपयोग कर रहा है, तो कथन बस है गलत है :
- इसका एक
DEFAULTक्लॉज है
- यह एक ट्रिगर द्वारा उत्पन्न किया जा सकता है
वापस UPDATE बयानों के लिए
यद्यपि उपरोक्त सभी डेटाबेसों के लिए सही है, मैं आपको आश्वासन दे सकता हूं कि ट्रिगर मुद्दा ओरेकल डेटाबेस के लिए भी सही है। निम्नलिखित एसक्यूएल पर विचार करें:
CREATE TABLE x (a INT PRIMARY KEY, b INT, c INT, d INT);
INSERT INTO x VALUES (1, 1, 1, 1);
CREATE OR REPLACE TRIGGER t
BEFORE UPDATE OF c, d
ON x
BEGIN
IF updating('c') THEN
dbms_output.put_line('Updating c');
END IF;
IF updating('d') THEN
dbms_output.put_line('Updating d');
END IF;
END;
/
SET SERVEROUTPUT ON
UPDATE x SET b = 1 WHERE a = 1;
UPDATE x SET c = 1 WHERE a = 1;
UPDATE x SET d = 1 WHERE a = 1;
UPDATE x SET b = 1, c = 1, d = 1 WHERE a = 1;
जब आप ऊपर चलाते हैं, तो आपको निम्न आउटपुट दिखाई देगा:
table X created.
1 rows inserted.
TRIGGER T compiled
1 rows updated.
1 rows updated.
Updating c
1 rows updated.
Updating d
1 rows updated.
Updating c
Updating d
जैसा कि आप देख सकते हैं कि सभी कॉलमों को हमेशा अपडेट करने वाला स्टेटमेंट हमेशा सभी कॉलमों के लिए ट्रिगर को फायर करेगा, जबकि केवल कॉलम को अपडेट करने वाले स्टेटमेंट केवल उन ट्रिगर्स को ही आग लगाएंगे जो ऐसे विशिष्ट बदलावों के लिए सुन रहे हैं।
दूसरे शब्दों में:
हाइबरनेट का वर्तमान व्यवहार जिसे आप वर्णन कर रहे हैं वह अधूरा है और यहां तक कि ट्रिगर्स (और शायद अन्य उपकरण) की उपस्थिति में भी इसे गलत माना जा सकता है।
मुझे व्यक्तिगत रूप से लगता है कि गतिशील SQL के मामले में आपके क्वेरी कैश ऑप्टिमाइज़ेशन तर्क को ओवरराइड किया गया है। निश्चित रूप से, इस तरह के कैश में कुछ और प्रश्न होंगे, और थोड़ा और पार्स करने का काम किया जाएगा, लेकिन यह आमतौर पर डायनेमिक UPDATEस्टेटमेंट के लिए समस्या नहीं है, जिसकी तुलना में बहुत कम है SELECT।
बैचिंग निश्चित रूप से एक मुद्दा है, लेकिन मेरी राय में, सभी कॉलमों को अपडेट करने के लिए एक एकल अद्यतन को सामान्यीकृत नहीं किया जाना चाहिए, क्योंकि बयान के बल्लेबाजी करने की थोड़ी संभावना है। संभावना है, ORM लगातार समान बयानों के उप-बैचों को इकट्ठा कर सकते हैं और "पूरे बैच" के बजाय बैच कर सकते हैं (यदि ORM "परिवर्तित" , "अशक्त" और "डिफ़ॉल्ट" के बीच अंतर को ट्रैक करने में भी सक्षम है)
UPDATEव्यावहारिक रूप सेDELETE+ के बराबर हैINSERT(क्योंकि आप वास्तव में पंक्ति का नया V ersion बनाते हैं )। ओवरहेड उच्च है, और अनुक्रमित की संख्या के साथ बढ़ता है , खासकर यदि उनमें से कई स्तंभ जो उन्हें शामिल करते हैं, वास्तव में अपडेट किए जाते हैं, और सूचकांक का प्रतिनिधित्व करने के लिए उपयोग किए जाने वाले पेड़ (या जो भी) को एक महत्वपूर्ण बदलाव की आवश्यकता होती है। यह उन कॉलमों की संख्या नहीं है जो अपडेट किए गए हैं जो प्रासंगिक हैं, लेकिन चाहे आप किसी इंडेक्स के कॉलम भाग को अपडेट करते हैं या नहीं।