2016-05-19 9 views
0

Ich möchte wissen, wie man eine Prozedur schreibt, die eine große Tabelle in kleinen Stücken aktualisiert. Es gibt Tonnen von Beispielen, aber in 90% von ihnen benutzen Leute TOP oder ROWCOUNT, die in MariaDB nicht verfügbar sind, und 10%, die lächerlich komplex sind.MariaDB UPDATE große Tabelle in kleine Stücke

(Update)
Dies ist der Code, den ich auf kleinen Brocken ausführen möchte.

UPDATE b_accounts BA 
INNER JOIN (
    SELECT SUM(AVG_DELIVERY_PRICE * AMOUNT_UNIT * AMOUNT) TOTAL_AVG_DELIVERY_PRICE 
     ,ACCOUNT_ID 
    FROM b_orders 
    GROUP BY ACCOUNT_ID 
    ) BO ON BA.ACCOUNT_ID = BO.ACCOUNT_ID 
SET BA.TOTAL_AVG_DELIVERY_PRICE = BO.TOTAL_AVG_DELIVERY_PRICE; 

Innerhalb b_accounts TABELLE gibt es über 200k Datensätze. Ich möchte immer noch UPDATE TOTAL_AVG_DELIVERY_PRICE aber 10k jede Iteration

+0

zeigen Sie Ihr verwandtes Schema und eine Probe Ihres Ziels an. – scaisEdge

+0

IMHO, es sieht aus wie Sie die falsche Methode auf das eigentliche Problem anwenden. Überprüfe meine Antwort und gib einen Kommentar, wenn du nicht einverstanden bist. – mootmoot

+0

'LIMIT' und' OFFSET' sind Gegenstücke zu 'TOP'. Siehe [_Tips on chunking_] (http://mysql.rjweb.org/doc.php/deletebig), einschließlich warum man 'OFFSET' nicht verwenden sollte. –

Antwort

0

IMHO, wird Ihr Verfahren funktionieren, aber es ist nicht eine effiziente und effektive Möglichkeit zur Aktualisierung von Echtzeit-Online-Daten, die Änderungen Rechnung tragen.

Ein Stapelverarbeitungsvorgang ist nur so gut wie die Verarbeitungszeit. Was, wenn 10 Datensätze in b_orders geändert werden, werden Sie die gesamte Prozedur für die 200k-Datensätze erneut ausführen? Egal wie effizient Ihr "Brocken" ist, Ihr b_account ist immer veraltet, wenn es Änderungen gibt. (Ich verstehe nicht, warum Leute vorschlagen, TOP, ROWCOUNT, während nicht die tatsächlichen Daten CUD Problem zu sehen)

Für Effizienz und einfach zu verstehen, sollten Sie (müssen in Ihrem Fall) erstellen eine vollständige CUD-Trigger für b_orders Tabelle.

Die Idee der CUD (create, update, delete) Trigger ist ziemlich einfach: Wann immer eine Änderung Aktion in b_orders Tabelle ist, führen Sie einfach die Berechnung und speichern Sie es in b_accounts.TOTAL_AVG_DELIVERY_PRICE.

Ein Beispiel für neuen Rekord Trigger, ist es sehr einfach

CREATE TRIGGER update_ AFTER BEFORE INSERT ON b_orders 
FOR EACH ROW 
BEGIN 
    UPDATE b_accounts 
    SET b_accounts.TOTAL_AVG_DELIVERY_PRICE = 
    ( SELECT SUM(AVG_DELIVERY_PRICE * AMOUNT_UNIT * AMOUNT) 
    from b_orders 
    where ACCOUNT_ID = NEW.ACCOUNT_ID) 
    WHERE ACCOUNT_ID = NEW.ACCOUNT_ID 
END; 

Updates für ähnliche Aktion erstellen, löschen. HINWEIS: Ich garantiere nicht die obige Triggersyntax-Richtigkeit, bitte schreibe deine eigenen. Diese Antwort, nur um Ihnen eine Idee zu geben, Ihr Problem zu lösen.

Um die Tabelle "b_accounts" zu aktualisieren, müssen Sie ein Dummy-Update für b_orders-Tabellen ausführen, indem Sie den Datensatz mit eindeutiger ACCOUNT_ID auswählen (damit Sie den Aktualisierungsvorgang nicht wiederholen, wenn Sie in der Tabelle b_orders in die gleiche account_id kommen). Der Trigger wird Ihre b_orders für jetzt und in Zukunft aktualisieren.

Verwandte Themen