Go to file
Johnathan Douglas dfb4a9a1da mass insert 2023-07-17 09:59:21 -03:00
app mass insert 2023-07-17 09:59:21 -03:00
bootstrap init 2023-07-07 15:00:23 +00:00
config categories 2023-07-13 17:17:49 -03:00
database mass insert 2023-07-17 09:59:21 -03:00
public init 2023-07-07 15:00:23 +00:00
resources init 2023-07-07 15:00:23 +00:00
routes init 2023-07-07 15:00:23 +00:00
storage init 2023-07-07 15:00:23 +00:00
tests init 2023-07-07 15:00:23 +00:00
.editorconfig init 2023-07-07 15:00:23 +00:00
.env.example migration 2023-07-07 12:09:06 -03:00
.gitattributes init 2023-07-07 15:00:23 +00:00
.gitignore init 2023-07-07 15:00:23 +00:00
README.md mass insert 2023-07-17 09:59:21 -03:00
artisan init 2023-07-07 15:00:23 +00:00
composer.json categories 2023-07-13 17:17:49 -03:00
composer.lock categories 2023-07-13 17:17:49 -03:00
package.json init 2023-07-07 15:00:23 +00:00
phpunit.xml init 2023-07-07 15:00:23 +00:00
vite.config.js init 2023-07-07 15:00:23 +00:00

README.md

Install

create database example-update-massive

configure .env

DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=example-update-massive
DB_USERNAME=default
DB_PASSWORD=secret

QUEUE_CONNECTION=database

ITEMS_COUNT=10000

ITEMS_COUNT é a variavel que irá definir quantos registros a fatory irá criar no banco de dados.

run migrate;

php artisan migrate:fresh --seed

Analyse Insert

Insert1

Insere um registro por vez.

insert into transactions (id, value, date)
values (1, 10, '2023-04-01');

insert into transactions (id, value, date)
values (2, 20, '2023-04-02');

insert into transactions (id, value, date)
values (3, 30, '2023-04-03');

Insert2

Realiza a inserção de forma multipla com todos os registros sendo passados no values de uma unica vez.

insert into transactions (id, value, date)
values (1, 10, '2023-04-01'),
       (2, 20, '2023-04-02'),
       (3, 30, '2023-04-03'), ....;

Nesse modelo, existe uma limitação:

SQLSTATE[HY000]: General error: 7 number of parameters must be between 0 and 65535

Insert3

Realiza a inserção de forma multipla com todos os registros sendo passados no values mas em blocos de 1.000 registros.

insert into transactions (id, value, date)
values (1, 10, '2023-04-01'),
       (2, 20, '2023-04-02'),
       (3, 30, '2023-04-03'), ....; --limit 1.000

insert into transactions (id, value, date)
values (1001, 50, '2023-04-01'),
       (1002, 60, '2023-04-02'),
       (1003, 70, '2023-04-03'), ....; --limit 1.000

MassInsert1

Result

quantity method time seconds
100 Insert1 0,016s
100 Insert2 0,001s
100 Insert3 0,001s
100 Insert4 0,044s
100 Insert5 0,040s
100 Insert6 0,125s
1.000 Insert1 1,000s
1.000 Insert2 0,09s
1.000 Insert3 0,09s
1.000 Insert4 0,09s
1.000 Insert5 0,09s
1.000 Insert6 0,09s
1.000 Insert3 0,09s
10.000 Insert1 14,25s
10.000 Insert2 0,88s
10.000 Insert3 0,83s
100.000 Insert1 (2m 38s) 158,41s
100.000 Insert2 error
100.000 Insert3 8,25s
1.000.000 Insert1 (31m 52s) 1952,32s
1.000.000 Insert2 error
1.000.000 Insert3 (1m 35s) 95s

Analyse Update

Grupo 1:

Atualizar um campo ou mais, mas o valor é o mesmo para um determinado grupo:

Update1Job

update transactions
set date=now(),
    value=1
where id = 1;

update transactions
set date=now(),
    value=1
where id = 2;

update transactions
set date=now(),
    value=1
where id = 3;
...

Update2Job

update transactions
set date=now(),
    value=1
where id in (1, 2, 3, . . .);

Result

quantity method time seconds performance
1.000 UpdateMassive1Job 1,00s -
1.000 UpdateMassive2Job 0,01s 100x
10.000 UpdateMassive1Job 14,00s -
10.000 UpdateMassive2Job 0,14s 100x
100.000 UpdateMassive1Job (2m 36s) 156,00s -
100.000 UpdateMassive2Job 1,00s 156x
1.000.000 UpdateMassive1Job (26m 10s) 1570,00s -
1.000.000 UpdateMassive2Job 15,00s 104x

Grupo 2:

Atualizar um campo ou mais, mas o valor é o diferente para cada registro:

Update3Job

update transactions
set date='2023-04-01',
    value=10
where id = 1;

update transactions
set date='2023-04-02',
    value=20
where id = 2;

update transactions
set date='2023-04-03',
    value=30
where id = 3;

Update4Job

update transactions
set date = case id when 1 then '2023-04-01'::date
     when 2 then '2023-04-02'::date 
     when 3 then '2023-04-03'::date
end
,
    value = case id when 1 then 10
     when 2 then 20 
     when 3 then 30
end
where id in (1, 2, 3);

Update5Job

update transactions as t
set date  = v.date,
    value = v.value from (
      values (1, '2023-04-01'::date, 10),
             (2, '2023-04-02'::date, 20),
             (3, '2023-04-03'::date, 30)
    ) as v(id, date, value)
where t.id = v.id;

Result

quantity method time seconds performance
1.000 UpdateMassive3Job 1,00s -
1.000 UpdateMassive4Job 0,08s 12x
1.000 UpdateMassive5Job 0,06s 16x
10.000 UpdateMassive3Job 14,00s -
10.000 UpdateMassive4Job 0,73s 19x
10.000 UpdateMassive5Job 0,59s 23x
100.000 UpdateMassive3Job (2m 44s) 164,00s -
100.000 UpdateMassive4Job 8,00s 20x
100.000 UpdateMassive5Job 7,00s 23x
1.000.000 UpdateMassive3Job (27m 10s) 1630,00s -
1.000.000 UpdateMassive4Job (1m 15s) 75,00s 21x
1.000.000 UpdateMassive5Job 58,00s 28x