मैं एक SQL अनुकूलन के बाद कुछ दिनों पहले यह सोच रहा था। मुझे लगता है कि हम सहमत हो सकते हैं कि एसक्यूएल विकिपीडिया की परिभाषा में एक "घोषित भाषा" है:
प्रोग्रामिंग प्रतिमान जो अपने नियंत्रण प्रवाह का वर्णन किए बिना गणना के तर्क को व्यक्त करता है
यदि आप सोचते हैं कि पर्दे के पीछे कितनी चीजें की जाती हैं (आंकड़ों को देखते हुए, यदि कोई इंडेक्स उपयोगी है, तो यह निर्णय लेना कि एक नेस्टेड, मर्ज या हैश में शामिल होना, आदि। आदि) हमें यह मानना होगा कि हम सिर्फ एक उच्च स्तर देते हैं तर्क, और डेटाबेस ने सभी निम्न स्तरीय नियंत्रण प्रवाह तर्क का ध्यान रखा।
इस परिदृश्य में भी, कभी-कभी डेटाबेस ऑप्टिमाइज़र को सर्वश्रेष्ठ परिणाम देने के लिए उपयोगकर्ता से कुछ "संकेत" की आवश्यकता होती है।
"घोषणात्मक" भाषा की एक और आम परिभाषा है (मुझे एक आधिकारिक स्रोत नहीं मिल सकता है):
प्रोग्रामिंग प्रतिमान जो इसे प्राप्त करने के चरणों का वर्णन किए बिना गणना के वांछित परिणाम को व्यक्त करता है (यह भी कि "क्या, कैसे नहीं" का वर्णन के साथ संक्षिप्त रूप में)
यदि हम इस परिभाषा को स्वीकार करते हैं, तो हम ओपी द्वारा वर्णित मुद्दों का सामना करते हैं।
पहला मुद्दा यह है कि एसक्यूएल हमें "समान परिणाम" को परिभाषित करने के लिए कई समकक्ष तरीके देता है। संभवतः यह एक आवश्यक बुराई है: एक भाषा को जितनी अधिक अभिव्यंजक शक्ति हम देते हैं, उतनी ही एक ही चीज़ को व्यक्त करने के लिए अलग-अलग तरीके होने की संभावना है।
एक उदाहरण के रूप में, मुझे इस प्रश्न को अनुकूलित करने के लिए एक बार पूछा गया है:
SELECT Distinct CT.cust_type, ct.cust_type_description
from customer c
INNER JOIN
Customer_type CT on c.cust_type=ct.cust_type;
चूंकि प्रकार ग्राहक से बहुत कम थे और cust_type
ग्राहक तालिका पर एक सूचकांक था , इसलिए मैंने इसे फिर से लिखकर एक महान सुधार प्राप्त किया है:
SELECT CT.cust_type, ct.cust_type_description
from Customer_type CT
Where exists ( select 1 from customer c
Where c.cust_type=ct.cust_type);
इस विशिष्ट मामले में, जब मैंने डेवलपर से पूछा कि वह क्या हासिल करना चाहता है, तो उसने मुझे बताया कि "मैं सभी ग्राहक प्रकार चाहता था, जिसके लिए मेरे पास कम से कम एक ग्राहक था", यह संयोग से कि कैसे ऑप्टिमाइज़र क्वेरी का वर्णन किया जा सकता है।
इसलिए, अगर मुझे एक समान और अधिक कुशल क्वेरी मिल सकती है, तो अनुकूलक ऐसा क्यों नहीं कर सकता है?
मेरा सबसे अच्छा अनुमान है कि यह दो मुख्य कारणों से है:
SQL तर्क व्यक्त करता है:
चूँकि एसक्यूएल उच्च-स्तरीय तर्क व्यक्त करता है, क्या हम वास्तव में हमें और हमारे तर्क को "आउट-मार्ट" करना चाहेंगे? मैं उत्साहपूर्वक "हाँ" चिल्लाऊंगा अगर यह सभी समय के लिए नहीं था तो मुझे आशावादी को सबसे कुशल निष्पादन पथ चुनने के लिए मजबूर करना पड़ा। मुझे लगता है कि आशावादी को अपना सर्वश्रेष्ठ (अपने तर्क को भी संशोधित करने) के लिए विचार करने की अनुमति हो सकती है, लेकिन बचाव के लिए आने के लिए हमें एक "संकेत तंत्र" दें जब कुछ पागल हो जाए (यह पहिया + ब्रेक होने जैसा होगा) एक स्वायत्त कार)।
अधिक विकल्प = अधिक समय
यहां तक कि सबसे अच्छा RDBMS ऑप्टिमाइज़र सभी संभावित निष्पादन पथों का परीक्षण नहीं करता है, क्योंकि उन्हें वास्तव में तेज़ होना चाहिए: 100ms से 10ms तक किसी क्वेरी को अनुकूलित करने के लिए कितना अच्छा होगा यदि मुझे हर बार सर्वश्रेष्ठ पथ चुनने में 100ms खर्च करने की आवश्यकता है? और यह हमारे "उच्च-स्तरीय तर्क" का सम्मान करने वाले अनुकूलक के साथ है। अगर यह भी सभी समकक्ष SQL प्रश्नों का परीक्षण करना चाहिए तो अनुकूलक समय कई बार बढ़ सकता है।
क्वेरी का एक और अच्छा उदाहरण कोई RDBMS फिर से लिखना वास्तव में करने में सक्षम है ( इस दिलचस्प ब्लॉग पोस्ट से )
SELECT t1.id, t1.value, SUM(t2.value)
FROM mytable t1
JOIN mytable t2
ON t2.id <= t1.id
GROUP BY t1.id, t1.value;
की तुलना में इसे लिखा जा सकता है (आवश्यक विश्लेषणात्मक कार्य)
SELECT id, value, SUM(t1.value) OVER (ORDER BY id)
FROM mytable
select whatever from sometable where FKValue in (select FKValue from sometable_2 where other_value = :param)
। यह देखने के लिए तुच्छ होना चाहिए कि एकexists
या एक के साथ इसे कैसे पुनर्स्थापित किया जाएjoin
।