Qualsiasi INSERT ... SELECT ...
query acquisisce un blocco CONDIVISO
sulle righe legge dalla tabella di origine in SELECT. Ma elaborando blocchi di righe più piccoli, il blocco non dura troppo a lungo.
La query con LIMIT ... OFFSET
sarà sempre più lento man mano che avanzi nella tabella di origine. A 10.000 righe per blocco, devi eseguire quella query 10.000 volte, ognuna deve ricominciare da capo ed eseguire la scansione della tabella per raggiungere il nuovo OFFSET.
Qualunque cosa tu faccia, copiare 100 milioni di righe richiederà del tempo. Sta facendo molto lavoro.
Userei pt-archiver , uno strumento gratuito progettato per questo scopo. Elabora le righe in "blocchi" (o sottoinsiemi). Regolerà dinamicamente la dimensione dei blocchi in modo che ogni blocco richieda 0,5 secondi.
La più grande differenza tra il tuo metodo e pt-archiver è che pt-archiver non usa LIMIT ... OFFSET
, cammina lungo l'indice della chiave primaria, selezionando blocchi di riga per valore anziché per posizione. Quindi ogni pezzo viene letto in modo più efficiente.
Re il tuo commento:
Mi aspetto che ridurre le dimensioni del batch e aumentare il numero di iterazioni renderà il problema delle prestazioni peggiore , non meglio.
Il motivo è che quando usi LIMIT
con OFFSET
, ogni query deve ricominciare dall'inizio della tabella e contare le righe fino a OFFSET
valore. Questo diventa sempre più lungo man mano che scorri la tabella.
Esecuzione di 20.000 query costose utilizzando OFFSET
richiederà più tempo rispetto all'esecuzione di 10.000 query simili. La parte più costosa non sarà leggere 5.000 o 10.000 righe o inserirle nella tabella di destinazione. La parte più costosa salterà attraverso circa 50.000.000 di righe, più e più volte.
Invece, dovresti scorrere la tabella per valori non per offset.
INSERT IGNORE INTO Table2(id, field2, field3)
SELECT f1, f2, f3
FROM Table1
WHERE id BETWEEN rowOffset AND rowOffset+limitSize;
Prima del ciclo, interroga MIN(id) e MAX(id) e avvia rowOffset
al valore minimo e torna al valore massimo.
Questo è il modo in cui funziona pt-archiver.