laravel-performance/README.md

222 lines
5.7 KiB
Markdown

# Install
create database `example-update-massive`
configure `.env`
```dotenv
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;
```shell
php artisan migrate:fresh --seed
```
# Analyse Insert
`Insert1`
Insere um registro por vez.
```sql
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.
```sql
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.
```sql
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](/app/Tasks/MassInsert/MassInsert1Task.php)
### 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`
```sql
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`
```sql
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`
```sql
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`
```sql
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`
```sql
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 |