ओरेकल के साथ पेजिंग


97

मैं ओरेकल से उतना परिचित नहीं हूं जितना मैं होना चाहूंगा। मेरे पास कुछ 250k रिकॉर्ड हैं, और मैं उन्हें प्रति पृष्ठ 100 प्रदर्शित करना चाहता हूं। वर्तमान में मेरे पास एक संग्रहीत कार्यविधि है, जो डेटा एडॉप्टर और डेटासेट का उपयोग करके डेटासेट के लिए एक लाख रिकॉर्ड के सभी तिमाही को पुनर्प्राप्त करता है, और संग्रहीत खरीद से परिणाम पर डेटाडैपफ़िल (डेटासेट) विधि। यदि मेरे पास "पृष्ठ संख्या" और "प्रति पृष्ठ अभिलेखों की संख्या" पूर्णांक मानों के रूप में मैं मापदंडों के रूप में पारित कर सकता हूं, तो उस विशेष खंड को वापस पाने का सबसे अच्छा तरीका क्या होगा। कहते हैं, अगर मैं 10 पेज नंबर के रूप में, और 120 पेजों की संख्या के रूप में पास करता हूं, तो चयनित स्टेटमेंट से यह मुझे 1200 के माध्यम से 1880 वां, या ऐसा कुछ देगा, मेरे सिर में मेरा गणित बंद हो सकता है।

मैं इसे .NET में C # के साथ कर रहा हूं, सोचा कि यह महत्वपूर्ण नहीं है, अगर मैं इसे sql साइड पर सही से प्राप्त कर सकता हूं, तो मुझे शांत होना चाहिए।

अपडेट: मैं ब्रायन के सुझाव का उपयोग करने में सक्षम था, और यह बहुत अच्छा काम कर रहा है। मैं कुछ अनुकूलन पर काम करना चाहता हूं, लेकिन पृष्ठ एक मिनट के बजाय 4 से 5 सेकंड में आ रहे हैं, और मेरा पेजिंग नियंत्रण मेरे नए संग्रहित प्रोक्स के साथ बहुत अच्छी तरह से एकीकृत करने में सक्षम था।

जवाबों:


144

कुछ इस तरह काम करना चाहिए: फ्रांसेस बुमा के ब्लॉग से

SELECT * FROM
(
    SELECT a.*, rownum r__
    FROM
    (
        SELECT * FROM ORDERS WHERE CustomerID LIKE 'A%'
        ORDER BY OrderDate DESC, ShippingDate DESC
    ) a
    WHERE rownum < ((pageNumber * pageSize) + 1 )
)
WHERE r__ >= (((pageNumber-1) * pageSize) + 1)

4
हां यह एक 'इन-बिल्ट' कॉलम है जो ओरेकल सपोर्ट करता है, यह हमेशा 1 पर शुरू होता है और प्रत्येक पंक्ति के लिए इंक्रीमेंट होता है। तो कोड के इस स्निपेट में, यदि आपके पास 1000 पंक्तियाँ हैं, तो क्रम क्रम लागू किया जाता है और फिर प्रत्येक पंक्ति को एक पंक्तिबद्ध सौंपा जाता है। बाहरी चयन (s) उन पंक्ति संख्याओं का उपयोग करते हैं, जिन्हें आप अपने पृष्ठ के आधार पर ढूंढ रहे 'पृष्ठ' का पता लगाने के लिए करते हैं।
ब्रायन श्मिट

9
यह अच्छा है, लेकिन बड़े चयनों पर बुरी तरह से धीमा है, बस यह जांचें कि 0 से 1000 और 500.000 से 501.000 तक का चयन करने का समय क्या होगा ... मैं इस तरह की चुनिंदा संरचना का उपयोग कर रहा था अब मैं वर्कअराउंड की खोज कर रहा हूं।
11

3
@ n3whous3 आप इसे आज़मा सकते हैं - inf.unideb.hu/~gabora/pagination/results.html
jasonk

7
मैंने सोचा कि क्यों दो WHEREके साथ नहीं जोड़ा जा सकता है AND, और फिर यह पाया: orafaq.com/wiki/ROWNUM
मेंगड़ी गाओ

1
ओरेकल पेजिनेशन मेरा दिन बर्बाद कर देता है।
ऑथरस

134

टॉम से पेजिंग पर और बहुत उपयोगी विश्लेषणात्मक कार्यों के बारे में पूछें

यह उस पृष्ठ का अंश है:

select * from (
    select /*+ first_rows(25) */
     object_id,object_name,
     row_number() over
    (order by object_id) rn
        from all_objects)
    where rn between :n and :m
        order by rn;

7
यह वास्तव में बहुत बेहतर कार्यान्वयन है, हालांकि उस पोस्ट पर इसे खोजना मुश्किल है। जब आपके पास बहुत सारे बड़े पृष्ठ हों, तो दूसरे उत्तर को सभी पंक्तियों से पहले के पन्नों पर भी जाना चाहिए। जटिल प्रश्नों में, इसका मतलब है कि बाद के पृष्ठ पहले के पृष्ठों की तुलना में खराब प्रदर्शन करते हैं।
talleth

@tallseth तुम सही हो। इसे उस पृष्ठ पर खोजना कठिन है। अंश जोड़ा जाता है।
चोबियस

यह सही उत्तर है जिसे आपको अपने आदेश को गतिशील रूप से बदलना चाहिए।
चकेड़ा

74

संपूर्णता के हित में, अधिक आधुनिक समाधान की तलाश कर रहे लोगों के लिए, ओरेकल 12 सी में बेहतर पेजिंग और शीर्ष हैंडलिंग सहित कुछ नई विशेषताएं हैं।

पेजिंग

पेजिंग इस तरह दिखता है:

SELECT *
FROM user
ORDER BY first_name
OFFSET 5 ROWS FETCH NEXT 10 ROWS ONLY;

शीर्ष एन रिकॉर्ड्स

शीर्ष रिकॉर्ड प्राप्त करना इस तरह दिखता है:

SELECT *
FROM user
ORDER BY first_name
FETCH FIRST 5 ROWS ONLY

ध्यान दें कि उपर्युक्त दोनों क्वेरी उदाहरणों में कैसे ORDER BYहैं। नए आदेश इनका सम्मान करते हैं और इन्हें सॉर्ट किए गए डेटा पर चलाया जाता है।

मैं के लिए एक अच्छा ओरेकल संदर्भ पृष्ठ नहीं मिला FETCHया OFFSETलेकिन यह पेज इन नई सुविधाओं के एक महान सिंहावलोकन है।

प्रदर्शन

जैसा कि @wweicker नीचे टिप्पणी में बताता है, प्रदर्शन 12 सी में नए वाक्यविन्यास के साथ एक मुद्दा है। मेरे पास परीक्षण करने के लिए 18c की प्रतिलिपि नहीं थी यदि Oracle ने इसे सुधार लिया है।

दिलचस्प बात यह है कि, मेरे वास्तविक परिणामों को पहली बार थोड़ा जल्दी वापस कर दिया गया था जब मैंने नई तालिका के लिए अपनी तालिका (113 मिलियन + पंक्तियों) पर प्रश्नों को चलाया:

  • नई विधि: 0.013 सेकंड।
  • पुरानी विधि: 0.107 सेकंड।

हालाँकि, जैसा कि @wweicker ने बताया है, नई योजना के लिए व्याख्या योजना बहुत खराब लग रही है:

  • नई विधि लागत: 300,110
  • पुरानी विधि लागत: 30

नए सिंटैक्स ने मेरे कॉलम पर सूचकांक का पूरा स्कैन किया, जो पूरी लागत थी। संभावना है, चीजें अनइंस्टॉल किए गए डेटा पर सीमित होने पर बहुत खराब हो जाती हैं।

आइए एक नज़र डालते हैं कि पिछले डेटासेट पर एक एकल अनएन्डेक्सेड कॉलम सहित:

  • नई विधि समय / लागत: 189.55 सेकंड / 998,908
  • पुरानी विधि समय / लागत: 1.973 सेकंड / 256

सारांश: जब तक ओरेकल इस हैंडलिंग में सुधार नहीं करता है तब तक सावधानी के साथ उपयोग करें। यदि आपके पास काम करने के लिए एक सूचकांक है, तो शायद आप नई पद्धति का उपयोग करके दूर हो सकते हैं।

उम्मीद है कि मेरे पास जल्द ही खेलने के लिए 18 सी की एक प्रति होगी और अपडेट हो सकती है


12 सी उपयोगकर्ताओं के लिए यह बहुत अच्छा जवाब है
लालजी गजेरा

1
सिंटेक्स क्लीनर है, लेकिन प्रदर्शन बदतर है ( dba-presents.com/index.php/dat डेटाबेस/oracle/… )
wweicker

जानकर अच्छा लगा, धन्यवाद @wweicker। उम्मीद है कि प्रदर्शन जल्द ही ओरेकल द्वारा तय हो जाता है; हालांकि, ओरेकल को जानना, यह एक दूर की उम्मीद हो सकती है!
जोएलक


@JoelC आपकी राय में कोई बदलाव हुआ है?
रयान

11

बस जवाब और टिप्पणियों को संक्षेप में प्रस्तुत करना चाहते हैं। पेजिंग करने के कई तरीके हैं।

12 सी से पहले ऑर्किटेक्ट / एफईटीसीएच कार्यक्षमता नहीं थी, इसलिए @jasonk द्वारा सुझाए गए अनुसार श्वेतपत्र देखें । फायदे और नुकसान की विस्तृत व्याख्या के साथ विभिन्न तरीकों के बारे में मैंने पाया यह सबसे पूरा लेख है। उन्हें यहां कॉपी-पेस्ट करने में काफी समय लगेगा, इसलिए मैं ऐसा नहीं करूंगा।

Jooq रचनाकारों का एक अच्छा लेख भी है जो कुछ सामान्य कैविएट को ओरेकल और अन्य डेटाबेस पेजिनेशन के साथ समझाते हैं। jooq का ब्लॉगपोस्ट

अच्छी खबर है, oracle 12c के बाद से हमारे पास एक नया OFFSET / FETCH कार्यक्षमता है। OracleMagazine 12c नई सुविधाएँ । कृपया "टॉप-एन क्वेरीज़ एंड पेजिनेशन" देखें

आप निम्नलिखित कथन जारी करके अपने oracle संस्करण की जाँच कर सकते हैं

SELECT * FROM V$VERSION

7

निम्नलिखित प्रयास करें:

SELECT *
FROM
  (SELECT FIELDA,
    FIELDB,
    FIELDC,
    ROW_NUMBER() OVER (ORDER BY FIELDC) R
  FROM TABLE_NAME
  WHERE FIELDA = 10
  )
WHERE R >= 10
AND R   <= 15;

[tecnicume] के माध्यम से


0

अपने प्रोजेक्ट में मैंने Oracle 12c और java का उपयोग किया । पेजिंग कोड इस तरह दिखता है:

 public public List<Map<String, Object>> getAllProductOfferWithPagination(int pageNo, int pageElementSize, Long productOfferId, String productOfferName) {
    try {

        if(pageNo==1){
            //do nothing
        } else{
            pageNo=(pageNo-1)*pageElementSize+1;
        }
        System.out.println("algo pageNo: " + pageNo +"  pageElementSize: "+ pageElementSize+"  productOfferId: "+ productOfferId+"  productOfferName: "+ productOfferName);

        String sql = "SELECT * FROM ( SELECT * FROM product_offer po WHERE po.deleted=0 AND (po.product_offer_id=? OR po.product_offer_name LIKE ? )" +
             " ORDER BY po.PRODUCT_OFFER_ID asc) foo OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";

       return jdbcTemplate.queryForList(sql,new Object[] {productOfferId,"%"+productOfferName+"%",pageNo-1, pageElementSize});

    } catch (Exception e) {
        System.out.println(e);
        e.printStackTrace();
        return null;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.