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

डीप नेस्टेड सबक्वेरी फैक्टरिंग (CTE) के लिए धीमा प्रदर्शन

Q1:ऐसा लगता है कि गणना समय के बारे में कुछ भी नहीं है, बस ऑप्टिमाइज़र एल्गोरिथ्म में बग है जो एक सर्वोत्तम निष्पादन योजना की गणना करते समय इसे पागल बना देता है।

Q2:Oracle 11.X.0.X में नेस्टेड प्रश्नों और क्वेरी फैक्टरिंग के अनुकूलन से संबंधित कई ज्ञात और निश्चित बग हैं। लेकिन कोई ठोस मुद्दा खोजना बहुत कठिन है।

Q3:दो अदस्तावेजीकृत हैं संकेत:materialize और inline लेकिन उनमें से कोई भी मेरे लिए काम नहीं करता है जबकि मैंने आपके उदाहरण की कोशिश की है। यह संभव है कि सर्वर कॉन्फ़िगरेशन में कुछ परिवर्तन या 11.2.0.3 में अपग्रेड करने से नेस्टेड with की सीमा बढ़ सकती है खंड:मेरे लिए (11.2.0.3 Win7/x86 पर) आपका उदाहरण ठीक काम करता है, लेकिन नेस्टेड तालिकाओं की संख्या बढ़ाकर 30 करने से एक सत्र रुक जाता है।

समाधान इस तरह दिख सकता है:

select k from (
select k, avg(k) over (partition by null) k_avg from ( --t16
  select k, avg(k) over (partition by null) k_avg from ( --t15
    select k, avg(k) over (partition by null) k_avg from ( --t14
      select k, avg(k) over (partition by null) k_avg from ( --t13
        select k, avg(k) over (partition by null) k_avg from ( --t12
          select k, avg(k) over (partition by null) k_avg from ( --t11
            select k, avg(k) over (partition by null) k_avg from ( --t10
              select k, avg(k) over (partition by null) k_avg from ( --t9
                select k, avg(k) over (partition by null) k_avg from ( --t8
                  select k, avg(k) over (partition by null) k_avg from ( --t7
                    select k, avg(k) over (partition by null) k_avg from ( --t6
                      select k, avg(k) over (partition by null) k_avg from ( --t5
                        select k, avg(k) over (partition by null) k_avg from ( --t4
                          select k, avg(k) over (partition by null) k_avg from ( --t3
                            select k, avg(k) over (partition by null) k_avg from ( --t2
                              select k, avg(k) over (partition by null) k_avg from ( -- t1
                                select k, avg(k) over (partition by null) k_avg from (select 0 as k from dual) t0
                              ) where k >= k_avg
                            ) where k >= k_avg
                          ) where k >= k_avg
                        ) where k >= k_avg
                      ) where k >= k_avg
                    ) where k >= k_avg
                  ) where k >= k_avg
                ) where k >= k_avg
              ) where k >= k_avg
            ) where k >= k_avg
          ) where k >= k_avg
        ) where k >= k_avg
      ) where k >= k_avg
    ) where k >= k_avg
  ) where k >= k_avg
) where k >= k_avg
)

कम से कम यह मेरे लिए 30 के नेस्टिंग स्तर पर काम करता है और WINDOW BUFFER के साथ पूरी तरह से अलग निष्पादन योजना तैयार करता है और VIEW LOAD TABLE AS SELECT के बजाय , SORT AGGREGATE और TABLE ACCESS FULL

अपडेट करें

  1. बस 11.2.0.4 (Win7/32bit) स्थापित करें और प्रारंभिक क्वेरी के विरुद्ध इसका परीक्षण करें। अनुकूलक व्यवहार में कुछ भी नहीं बदला।

  2. inline . के उपयोग से भी CBO के व्यवहार को सीधे तौर पर प्रभावित करने की कोई संभावना नहीं है (अनियंत्रित) या RULE (बहिष्कृत) संकेत। हो सकता है कि कुछ गुरु कुछ प्रकार जानते हों, लेकिन यह मेरे लिए एक शीर्ष रहस्य है (और Google भी :-)।

  3. उचित समय में एक चयन कथन में चीजें करना संभव है यदि एक मुख्य चयन कथन को भागों में विभाजित किया जाता है और फ़ंक्शन में रखा जाता है जो पंक्तियों का एक सेट देता है (फ़ंक्शन sys_refcursor या मजबूत टाइप किया गया कर्सर लौटाता है), लेकिन यह कोई विकल्प नहीं है यदि कोई क्वेरी रनटाइम पर निर्मित।

  4. एक्सएमएल के उपयोग के साथ समाधान संभव है, <स्ट्राइक>लेकिन यह संस्करण गधे के छेद के माध्यम से एक टन्सिल को हटाने जैसा दिखता है (क्षमा करें):

select
  extractvalue(column_value,'/t/somevalue') abc
from 
  table(xmlsequence((
    select t2 from (
      select
        t0,
        t1,
        (   
          select xmlagg(
                   xmlelement("t", 
                     xmlelement("k1",extractvalue(t1t.column_value,'/t/k1')), 
                     xmlelement("somevalue", systimestamp))
                  )
          from 
            table(xmlsequence(t0)) t0t, 
            table(xmlsequence(t1)) t1t  
          where 
            extractvalue(t1t.column_value,'/t/k1') >= (
              select avg(extractvalue(t1t.column_value, '/t/k1')) from table(xmlsequence(t1))
            )                                              
            and 
            extractvalue(t0t.column_value,'/t/k2') > 6
        ) t2
      from (
        select
          t0,
          (
            select xmlagg(
                     xmlelement("t", 
                       xmlelement("k1",extractvalue(column_value,'/t/k1')), 
                       xmlelement("somevalue", sysdate))
                    )
            from table(xmlsequence(t0))   
            where 
              extractvalue(column_value,'/t/k1') >= (
                select avg(extractvalue(column_value, '/t/k1')) from table(xmlsequence(t0))
              )
          ) t1
        from (
          select
            xmlagg(xmlelement("t", xmlelement("k1", level), xmlelement("k2", level + 3))) t0
          from dual connect by level < 5
        )
      )
    )
  )))

ऊपर एक अजीब कोड के बारे में एक और बात यह है कि यह संस्करण केवल तभी लागू होता है जब with डेटा सेट में बड़ी संख्या में पंक्तियाँ नहीं थीं।



  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. जेपीए/हाइबरनेट के साथ किसी बच्चे की आईडी में माता-पिता की आईडी का संदर्भ कैसे लें?

  3. सी # को ओरेकल से जोड़ना

  4. Oracle, Postgres और SQL Server में स्ट्रिंग कॉन्सटेनेशन ऑपरेटर

  5. क्या % प्रकार का प्रयोग वस्तु प्रकार के साथ किया जा सकता है? क्या यह संभव है क्योंकि ऐसा करने का प्रयास करते समय मुझे त्रुटि मिल रही है?