2012-10-13 20 views
5

क्या एक ही क्वेरी में एक ही कुल फ़ंक्शन पर एकाधिक कॉल के लिए SQL कार्यान्वयन पर मानक है?क्या SQL कुल फ़ंक्शन गणना के लिए कोई मानक है?

उदाहरण के लिए, निम्न उदाहरण पर विचार एक लोकप्रिय उदाहरण स्कीमा के आधार पर:

SELECT Customer,SUM(OrderPrice) FROM Orders 
GROUP BY Customer 
HAVING SUM(OrderPrice)>1000 

मुमकिन है, यह योग (OrderPrice) के मूल्य की गणना करने अभिकलन समय लगता है। क्या यह लागत कुल कार्य के प्रत्येक संदर्भ के लिए खर्च की गई है, या परिणाम किसी विशेष क्वेरी के लिए संग्रहीत किया गया है?

या, इस मामले के लिए एसक्यूएल इंजन कार्यान्वयन के लिए कोई मानक नहीं है?

उत्तर

3

हालांकि मैंने कई अलग-अलग डीबीएमएस के साथ काम किया है, मैं केवल आपको SQL सर्वर पर इसे साबित करने का परिणाम दिखाऊंगा। इस क्वेरी पर विचार करें, जिसमें अभिव्यक्ति में एक CAST भी शामिल है। क्वेरी प्लान को देखते हुए, अभिव्यक्ति sum(cast(number as bigint)) केवल एक बार ली जाती है, जिसे DEFINE:([Expr1005]=SUM([Expr1006])) के रूप में परिभाषित किया जाता है।

set showplan_text on 
select type, sum(cast(number as bigint)) 
from master..spt_values 
group by type 
having sum(cast(number as bigint)) > 100000 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
    |--Filter(WHERE:([Expr1005]>(100000))) 
     |--Hash Match(Aggregate, HASH:([Expr1004]), RESIDUAL:([Expr1004] = [Expr1004]) DEFINE:([Expr1005]=SUM([Expr1006]))) 
      |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(nchar(3),[mssqlsystemresource].[sys].[spt_values].[type],0), [Expr1006]=CONVERT(bigint,[mssqlsystemresource].[sys].[spt_values].[number],0))) 
       |--Index Scan(OBJECT:([mssqlsystemresource].[sys].[spt_values].[ix2_spt_values_nu_nc])) 

यह बहुत स्पष्ट ऊपर, नहीं हो सकता है के बाद से यह चयन परिणाम प्रदर्शित नहीं करता है, तो मैं नीचे क्वेरी के लिए एक *10 जोड़ लिया है। ध्यान दें कि इसमें अब एक अतिरिक्त चरण DEFINE:([Expr1006]=[Expr1005]*(10)) (शीर्ष पर नीचे चलाएं चरण) शामिल हैं जो दर्शाता है कि नई अभिव्यक्ति को अतिरिक्त गणना करने के लिए आवश्यक है। फिर भी, यह भी अनुकूलित है, क्योंकि यह पूरी अभिव्यक्ति का पुनर्मूल्यांकन नहीं करता है - केवल, यह Expr1005 ले रहा है और 10 से गुणा कर रहा है!

set showplan_text on 
select type, sum(cast(number as bigint))*10 
from master..spt_values 
group by type 
having sum(cast(number as bigint)) > 100000 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
    |--Compute Scalar(DEFINE:([Expr1006]=[Expr1005]*(10))) 
     |--Filter(WHERE:([Expr1005]>(100000))) 
      |--Hash Match(Aggregate, HASH:([Expr1004]), RESIDUAL:([Expr1004] = [Expr1004]) DEFINE:([Expr1005]=SUM([Expr1007]))) 
       |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(nchar(3),[mssqlsystemresource].[sys].[spt_values].[type],0), [Expr1007]=CONVERT(bigint,[mssqlsystemresource].[sys].[spt_values].[number],0))) 
         |--Index Scan(OBJECT:([mssqlsystemresource].[sys].[spt_values].[ix2_spt_values_nu_nc])) 

इस तरह अन्य सभी डीबीएमएस के रूप में अच्छी तरह से काम करते हैं, कम से कम प्रमुख हैं अर्थात PostgreSQL, Sybase, ओरेकल, डीबी 2, Firebird, MySQL पर विचार बहुत संभावना है।

संबंधित मुद्दे