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

बड़ी टेबल पर OFFSET के साथ क्वेरी को ऑप्टिमाइज़ करें

एक बड़ा OFFSET हमेशा धीमा रहेगा। पोस्टग्रेज़ को सभी पंक्तियों को क्रमित करना होता है और दृश्यमान . की गणना करनी होती है आपके ऑफसेट तक वाले। पिछली सभी पंक्तियों को छोड़ने के लिए सीधे आप एक अनुक्रमित row_number जोड़ सकते हैं तालिका में (या एक MATERIALIZED VIEW बनाएं) उक्त row_number . सहित ) और WHERE row_number > x . के साथ काम करें OFFSET x . के बजाय ।

हालाँकि, यह दृष्टिकोण केवल-पढ़ने के लिए (या अधिकतर) डेटा के लिए ही समझदार है। तालिका डेटा के लिए इसे लागू करना जो समवर्ती रूप से बदल सकता है अधिक चुनौतीपूर्ण है। आपको वांछित व्यवहार को परिभाषित करके प्रारंभ करना होगा बिल्कुल

मैं पेजिनेशन . के लिए एक अलग दृष्टिकोण सुझाता हूं :

SELECT *
FROM   big_table
WHERE  (vote, id) > (vote_x, id_x)  -- ROW values
ORDER  BY vote, id  -- needs to be deterministic
LIMIT  n;

जहां vote_x और id_x अंतिम . से हैं पिछला पृष्ठ . की पंक्ति (दोनों के लिए DESC और ASC ) या पहले . से अगर नेविगेट कर रहे हैं पीछे की ओर

पंक्ति मानों की तुलना आपके पास पहले से मौजूद इंडेक्स द्वारा समर्थित है - एक ऐसी सुविधा जो आईएसओ एसक्यूएल मानक का अनुपालन करती है, लेकिन प्रत्येक आरडीबीएमएस इसका समर्थन नहीं करता है।

CREATE INDEX vote_order_asc ON big_table (vote, id);

या अवरोही क्रम के लिए:

SELECT *
FROM   big_table
WHERE  (vote, id) < (vote_x, id_x)  -- ROW values
ORDER  BY vote DESC, id DESC
LIMIT  n;

समान अनुक्रमणिका का उपयोग कर सकते हैं।
मेरा सुझाव है कि आप अपने कॉलम घोषित करें NOT NULL या अपने आप को NULLS FIRST|LAST . से परिचित कराएं निर्माण:

  • डेटाटाइम एएससी द्वारा पोस्टग्रेएसक्यूएल सॉर्ट करें, पहले शून्य?

नोट दो बातें विशेष रूप से:

  1. ROW WHERE . में मान खंड को अलग किए गए सदस्य क्षेत्रों से बदला नहीं जा सकता। WHERE (vote, id) > (vote_x, id_x) नहीं के साथ प्रतिस्थापित किया जाए:

    WHERE  vote >= vote_x
    AND    id   > id_x

    इससे सब का पता नहीं चलेगा id <= id_x . के साथ पंक्तियाँ , जबकि हम केवल उसी वोट के लिए ऐसा करना चाहते हैं, अगले के लिए नहीं। सही अनुवाद होगा:

    WHERE (vote = vote_x AND id > id_x) OR vote > vote_x
    

    ... जो इंडेक्स के साथ अच्छी तरह से नहीं चलता है, और अधिक कॉलम के लिए तेजी से जटिल हो जाता है।

    एक एकल . के लिए आसान होगा कॉलम, जाहिर है। यही वह विशेष मामला है जिसका मैंने शुरुआत में उल्लेख किया था।

  2. तकनीक ORDER BY . में मिश्रित दिशाओं के लिए काम नहीं करती है जैसे:

    ORDER  BY vote ASC, id DESC
    

    कम से कम मैं जेनेरिक . के बारे में नहीं सोच सकता इसे कुशलतापूर्वक लागू करने का तरीका। यदि दोनों स्तंभों में से कम से कम एक संख्यात्मक प्रकार है, तो आप (vote, (id * -1)) पर उल्टे मान वाले कार्यात्मक अनुक्रमणिका का उपयोग कर सकते हैं - और ORDER BY . में उसी एक्सप्रेशन का उपयोग करें :

    ORDER  BY vote ASC, (id * -1) ASC
    

संबंधित:

  • 'WHERE (col1, col2) <(val1, val2)'
  • के लिए SQL सिंटैक्स शब्द
  • कई तालिकाओं के स्तंभों के साथ क्रम के लिए प्रदर्शन में सुधार करें

विशेष रूप से मार्कस विनैंड I द्वारा प्रस्तुत प्रस्तुति पर ध्यान दें:

  • "पेजिनेशन ने पोस्टग्रेएसक्यूएल तरीके से किया"


  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. PostgreSQL विशेषाधिकार और उपयोगकर्ता प्रबंधन - आपको क्या पता होना चाहिए

  4. रिकर्सिव सीटीई मनमानी बिंदु से माता-पिता के साथ फ़ील्ड को जोड़ता है

  5. पंक्ति प्रकार की जाँच करते समय IS NOT NULL गलत क्यों है?