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

बड़ी संख्या में रिकॉर्ड चलाने के लिए हमेशा के लिए कार्य करना

सबसे अधिक संभावना है कि आप दौड़ की स्थिति में भाग रहे हैं . जब आप अलग लेन-देन . में अपने फ़ंक्शन को एक के बाद एक 1000 बार त्वरित क्रम में चलाते हैं , कुछ ऐसा होता है:

T1            T2            T3            ...
SELECT max(id) -- id 1
              SELECT max(id)  -- id 1
                            SELECT max(id)  -- id 1
                                          ...
              Row id 1 locked, wait ...
                            Row id 1 locked, wait ...
UPDATE id 1
                                          ... 

COMMIT
              Wake up, UPDATE id 1 again!
              COMMIT
                            Wake up, UPDATE id 1 again!
                            COMMIT
                                          ... 

SQL फ़ंक्शन के रूप में बड़े पैमाने पर पुनर्लेखित और सरलीकृत:

CREATE OR REPLACE FUNCTION get_result(val1 text, val2 text)
  RETURNS text AS 
$func$
   UPDATE table t
   SET    id_used = 'Y'
        , col1 = val1
        , id_used_date = now() 
   FROM  (
      SELECT id
      FROM   table 
      WHERE  id_used IS NULL
      AND    id_type = val2
      ORDER  BY id
      LIMIT  1
      FOR    UPDATE   -- lock to avoid race condition! see below ...
      ) t1
   WHERE  t.id_type = val2
   -- AND    t.id_used IS NULL -- repeat condition (not if row is locked)
   AND    t.id = t1.id
   RETURNING  id;
$func$  LANGUAGE sql;

बहुत अधिक स्पष्टीकरण के साथ संबंधित प्रश्न:

व्याख्या करें

  • बोल्ड जोर मेरा। सौभाग्य से, आप min(id) . को बदल सकते हैं आसानी से समतुल्य ORDER BY . के साथ / LIMIT 1 मैंने ऊपर प्रदान किया। इंडेक्स का भी उपयोग कर सकते हैं।

  • अगर टेबल बड़ी है, तो आपको जरूरत id . पर एक इंडेक्स कम से कम। मान लें कि id पहले से ही PRIMARY KEY के रूप में अनुक्रमित है , इससे मदद मिलेगी। लेकिन यह अतिरिक्त आंशिक बहु-स्तंभ अनुक्रमणिका शायद और भी बहुत कुछ में मदद करेगा :

    CREATE INDEX foo_idx ON table (id_type, id)
    WHERE id_used IS NULL;
    

वैकल्पिक समाधान

सलाहकार ताले यहां बेहतर तरीका हो सकता है:

या हो सकता है कि आप एक साथ कई पंक्तियों को लॉक करना चाहें :




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres . का उपयोग करके एक बार में 3 तालिकाओं में डेटा डालें

  2. ZIpped फ़ाइल को Postgres तालिका में कैसे आयात करें

  3. कई अलग-अलग तालिकाओं के लिए एकल ट्रिगर प्रक्रिया लागू करें

  4. जब स्थिति <> सत्य होती है तो PostgreSQL शून्य मान क्यों नहीं लौटाता है?

  5. मान के आधार पर किसी स्ट्रिंग को सूची से किसी अन्य स्ट्रिंग से बदलें