Mysql
 sql >> Database >  >> RDS >> Mysql

Aggiorna la tabella MySQL in blocchi

Ho finito con la procedura elencata di seguito. Funziona ma non sono sicuro che sia efficiente con tutte le query per identificare intervalli consecutivi. Può essere chiamato con i seguenti argomenti (esempio):

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

Fondamentalmente, il primo argomento è il comando di aggiornamento (ad esempio qualcosa come "set x =..."), seguito dal nome della tabella mysql, seguito da una chiave numerica (intera) che deve essere univoca, seguita dalla dimensione del pezzi da elaborare. La chiave dovrebbe avere un indice per prestazioni ragionevoli. La variabile "n" e le istruzioni "select" nel codice seguente possono essere rimosse e servono solo per il debug.

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//