Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Aktualisieren Sie die MySQL-Tabelle in Blöcken

Ich endete mit dem unten aufgeführten Verfahren. Es funktioniert, aber ich bin mir nicht sicher, ob es bei allen Abfragen effizient ist, aufeinanderfolgende Bereiche zu identifizieren. Es kann mit folgenden Argumenten aufgerufen werden (Beispiel):

call chunkUpdate('SET var=0','someTable','theKey',500000);

Grundsätzlich ist das erste Argument der Aktualisierungsbefehl (z. B. so etwas wie "set x =..."), gefolgt vom Namen der mysql-Tabelle, gefolgt von einem numerischen (ganzzahligen) Schlüssel, der eindeutig sein muss, gefolgt von der Größe der Brocken zu verarbeiten. Der Schlüssel sollte einen Index für eine angemessene Leistung haben. Die "n"-Variable und die "select"-Anweisungen im folgenden Code können entfernt werden und dienen nur zum Debuggen.

delimiter //
CREATE PROCEDURE chunkUpdate (IN cmd VARCHAR(255), IN tab VARCHAR(255), IN ky VARCHAR(255),IN sz INT)
BEGIN
  SET @sqlgetmin = CONCAT("SELECT MIN(",ky,")-1 INTO @minkey FROM ",tab); 
  SET @sqlgetmax = CONCAT("SELECT MAX(",ky,") INTO @maxkey FROM ( SELECT ",ky," FROM ",tab," WHERE ",ky,">@minkey ORDER BY ",ky," LIMIT ",sz,") AS TMP"); 
  SET @sqlstatement = CONCAT("UPDATE ",tab," ",cmd," WHERE ",ky,">@minkey AND ",ky,"<[email protected]");
  SET @n=1;

  PREPARE getmin from @sqlgetmin;
  PREPARE getmax from @sqlgetmax;
  PREPARE statement from @sqlstatement;

  EXECUTE getmin;

  REPEAT
    EXECUTE getmax; 
    SELECT cmd,@n AS step, @minkey AS min, @maxkey AS max;
    EXECUTE statement;
    set @[email protected];
    set @[email protected]+1;
  UNTIL @maxkey IS NULL
  END REPEAT; 
  select CONCAT(cmd, " EXECUTED IN ",@n," STEPS") AS MESSAGE;
END//