2011-11-21 22 views
5

मेरे पास ओरेकल में एक भौतिक दृश्य है जिसमें एक बाएं जॉइन शामिल है जो अद्यतन करने में बहुत लंबा समय लगता है। जब मैं अंतर्निहित तालिका को अद्यतन करता हूं तो इसे चलाने के लिए 63914.765 एस लगता है (हाँ यह लगभग 17 घंटे है)।ओरेकल - तेज़ रिफ्रेश बाएं जॉइन अपडेट के साथ मटेरियल विचार बहुत धीमे

मैं एक ही टेबल पर एक बाएं जॉइन का उपयोग कर रहा हूं, क्योंकि मैं डेटा से पंक्तियों तक डेटा को पिट करना चाहता हूं। पिवॉट कमांड इस ओरेकल संस्करण में उपलब्ध नहीं है, और एक ग्रुप BY + CASE का उपयोग तेजी से संदर्भित सामग्री पर देखने की अनुमति नहीं है।

materialized देखें लॉग इस तरह दिखता है:

CREATE MATERIALIZED VIEW Mv_Web_Programmes 
REFRESH FAST ON COMMIT 
AS 

SELECT 
    t1.ProgrammeId,   
    t1.Title as MainTitle, 
    t2.Title as SecondaryTitle, 
    --Primary key 
    t1.Title_Id as t1_titleId, 
    t2.Title_Id as t2_titleId, 

    t1.rowid as t1_rowid, 
    t2.rowid as t2_rowid 
FROM 
    Programmes_Titles t1, 
    Programmes_Titles t2 
WHERE 
    t1.Titles_Group_Type = 'mainTitle' 
    AND t1.Programme_Id = t2.Programme_Id(+) AND t2.Titles_Group_Type(+) = 'secondaryTitle' 

अद्यतन बयान:

CREATE MATERIALIZED VIEW LOG ON Programmes_Titles 
WITH PRIMARY KEY, rowid 
INCLUDING NEW Values; 

materialized ही दृश्य इस तरह दिखता है (यह 700000 पंक्तियाँ, Programmes_Titles तालिका 900000 पंक्तियाँ शामिल होता है) मैं इसका उपयोग करता हूं:

UPDATE Programmes_Titles 
SET Title = 'New title' 
WHERE rowid = 'AAAL4cAAEAAAftTABB' 

यह अद्यतन विवरण टा केएस 17 घंटे। एक इनर जॉइन का उपयोग करते समय ((+) को हटाएं) यह मिलीसेकंड लेता है।

मैंने एमवी_वेब_Programmes मटेरियलाइज्ड व्यू पर INDEXES जोड़ने का भी प्रयास किया, लेकिन ऐसा लगता है कि यह भी मदद नहीं करता था। (यह अभी भी एक मिनट से अधिक समय तक चलता है, जो धीमा करने का तरीका है, मैं हर बदलाव के 17 घंटे बाद इंतजार नहीं कर रहा हूं, इसलिए यह अद्यतन में सुधार हो सकता है)

तो मेरा सवाल है: इतने लंबे समय क्यों लेते हैं अंतर्निहित तालिका अद्यतन करने के लिए? मैं इसे कैसे सुधार सकता हूं?

उत्तर

3

मैंने आपकी समस्या को 10.2.0.3 उदाहरण पर पुन: उत्पन्न करने में कामयाब रहा है। स्वयं और बाहरी-जोड़ना बड़ी समस्या प्रतीत होता है (हालांकि एमवी के प्रत्येक कॉलम पर इंडेक्स के साथ अंततः एक मिनट के भीतर अपडेट किया गया)।

पहले तो मैंने सोचा कि आप एक समग्र एमवी इस्तेमाल कर सकते हैं:,

SQL> CREATE MATERIALIZED VIEW LOG ON Programmes_Titles 
    2 WITH PRIMARY KEY, ROWID (programmeId, Titles_Group_Type, title) 
    3 INCLUDING NEW Values; 

Materialized view log created 

SQL> CREATE MATERIALIZED VIEW Mv_Web_Programmes 
    2 REFRESH FAST ON COMMIT 
    3 AS 
    4 SELECT ProgrammeId, 
    5   MAX(decode(t1.Titles_Group_Type, 'mainTitle', t1.Title)) MainTl, 
    6   MAX(decode(t1.Titles_Group_Type, 'secondaryTitle', t1.Title)) SecTl 
    7 FROM Programmes_Titles t1 
    8 GROUP BY ProgrammeId; 

Materialized view created 

दुर्भाग्य के रूप में आपने गौर किया, a MV that contains MIN or MAX can only be fast-refreshed on commit after insert 10g के रूप में (तथाकथित डालने-केवल एमवी)। उपर्युक्त समाधान अपडेट/डिलीट के लिए काम नहीं करेगा (एमवी को मैन्युअल रूप से रीफ्रेश करना होगा)।

आप अपने सत्र का पता लगा सकते हैं और यह देखने के लिए ट्रेस फ़ाइल खोल सकते हैं कि SQL क्वेरी निष्पादित की जाती है ताकि आप यह पा सकें कि आप इसे इंडेक्स के माध्यम से अनुकूलित कर सकते हैं या नहीं।

+0

धन्यवाद, सुझाया गया समाधान सही काम करता है। बस एक अतिरिक्त सवाल है। मेरे उदाहरण क्वेरी में मैं केवल जॉइन में एक मानदंड का उपयोग करता हूं, लेकिन मेरी असली क्वेरी दो का उपयोग करती है। क्या मैं अभी भी DECODE फ़ंक्शन का उपयोग कर सकता हूं (यह मेरे लिए एक नया है या मुझे इसके बजाय CASE का उपयोग करना चाहिए?) – Tejo

+0

क्षमा करें, मैं थोड़ा तेज़ था। Programme_Titles तालिका को दूसरे मान के साथ नए मान के साथ अपडेट किया जाता है, लेकिन Mv_Web_Programmes अपडेट नहीं होता है, पुराना मान अभी भी वहां है। कोई विचार? – Tejo

+0

आपको DECODE के बजाय CASE का उपयोग करने में सक्षम होना चाहिए जब तक कि आप अपने केस स्टेटमेंट में उपयोग किए जाने वाले प्रत्येक कॉलम को एमवी लॉग में भी न करें। –

1

हम भी ओरेकल 11.2.0.3

पर हाल ही में इस मुद्दे का सामना करना पड़ा हमारे मामले में, इसे हटाने के लिए करने के लिए एक कार्यात्मक प्रभाव के कारण 'बाहरी शामिल हों' अपरिहार्य था।

जांच पर, यह पाया गया कि ओरेकल एमवी रीफ्रेश डीएमएल के साथ एक बुरा HASH_SH (हैश सेमी जॉइन) संकेत जोड़ रहा था।

कुछ भी नहीं ब्लॉग http://www.adellera.it/blog/2010/03/11/fast-refresh-of-join-only-mvs-_mv_refresh_use_stats-and-locking-log-stats/#comment-2975

निम्नलिखित अंत में में वर्णित बातों सहित काम किया, एक छिपे हुए संकेत काम किया ...

(हालांकि सामान्य रूप में, यह आवेदन यदि संभव हो तो में परिवर्तन करके बचा जाना चाहिए)

ओरेकल डॉक आईडी 1 9 4 9 537.1 सुझाव देता है कि छुपा _mv_refresh_use_hash_sj पैरामीटर को FALSE पर सेट करना उस संकेत का उपयोग करके इसे रोकना चाहिए।

alter session set "_mv_refresh_use_hash_sj"=FALSE; 

जिसने सीबीओ को HASH_SJ संकेत का उपयोग करके रोक दिया।

इसे दूसरों के हितों में यहां पोस्ट करना।