laravel-performance/README.md

5.7 KiB

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