» »

[MariadDB] Kakšen je najhitrejši vnos (delne) vrednosti stolpca 1 v stolpec 2?

[MariadDB] Kakšen je najhitrejši vnos (delne) vrednosti stolpca 1 v stolpec 2?

HotBurek ::

Dobro jutro.


Evo, tokrat gre pa za preprost problem, kjer se išče rešitev, ki se najhitreje izvede.

Tabela table_1 imam stolpec id, kjer je vnešen podatek v sledeči obliki:

000421-2-000007011

Tej tabeli bi rad dodal nov stolpec shop_id, ter v ta stolpec shranil vrednost, ki "pride" iz vrednosti v stolpcu id:
SUBSTRING(`id`, 1, 6)

Tabela ima 476,605,116 row-ov.

Kako se tega lotit, da bo zadeva zmerno hitro končnana?
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

DamijanD ::

mogoče bi bilo najhitreje, če bi naredili select into table1_new in potem samo rename tabele iz table1_new v table1 (pred tem seveda dropneš originalno tabelo) - tako se ogneš update stavkom v celoti.

Če pa delaš z updateom, pa kar simple direktni update + nujno ne smeš imet indexa na stolpcu shop_id, da ga ne bo sproti updatal. Če rabiš index, ga kreiraj šele po updatu.

HotBurek ::

Na prvo opcijo niti nisem pomislil. Zgleda ok.

No, odločil sem se za drugo opcijo.

Dodal sem nov stolpec 'shop_id', ter vanj uspešno shranil vrednost, ki pride iz sosednjega stolpca 'id'.

A brez keč-d-keč-a ne gre. Za stolpec 'shop_id' želim spremenit default value, ter da ne dovoli NULL.

Like this:

SET autocommit = 0;

LOCK TABLE `database_1`.`table_1` WRITE;

ALTER TABLE `database_1`.`table_1` MODIFY COLUMN `shop_id` INT(11) NOT NULL;

COMMIT;

UNLOCK TABLE;

SET autocommit = 1;

In guess what. Diska zmanjka, preden konča. Krneki ...

SQL Error [1114] [HY000]: (conn=34) The table 'table_1' is full

Prostora na disku je še 10GB. Zakaj sploh rabi 10GB (oz. še več) za tak update/alter?

Vidim pa, da na lokaciji /var/lib/mysql/database_1/ naredi file #sql-alter-1b37a-22.ibd, in tail -f kaže, da tu notri meče celotno vsebino tabele 'table_1'. Zakaj?

Po videnih id-jih, ki jih prikaže tail, pride nekje do polovice. Se pravi, potreboval bi 20GB prostora za ta alter. Tabela, na kateri delam alter, zasede 41GB na disku.

So kakšne "in-place" opcije, brez temp fajlov?
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

Zgodovina sprememb…

  • spremenilo: HotBurek ()

HotBurek ::

Evo, gremo plan B.

Tole je začetek:

ALTER TABLE `database_1`.`table_1` DROP COLUMN `shop_id`;

ALTER TABLE `database_1`.`table_1` ADD `shop_id` INT(11) DEFAULT -1 NOT NULL AFTER `id`;

Zdej pa udpdate, kjer bom nastavil vrednost 'shop_id' (generirana iz vrednosti 'id'). Lets see.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

Zgodovina sprememb…

  • spremenilo: HotBurek ()

DamijanD ::

Stari v trenutnih časih je najceneje dokupit/nadgradit HW - če upoštevaš čas, ki ga zabiješ pri reševanju problemov, ki jih imaš zaradi premalo placa...

no comment ::

HotBurek je izjavil:


In guess what. Diska zmanjka, preden konča. Krneki ...


https://mariadb.com/kb/en/innodb-online... ?

HotBurek ::

No, tole je pa uporabna dokumentacija.

Ampak, kolikor sem bral, bo potrebno še preverit kak to v praksi funkcionira.

Ravnokar pognal:

SET SESSION alter_algorithm='INPLACE';

OPTIMIZE TABLE `database_1`.`table_1`;

In, kot piše v dokumentaciji, v določenih primerih ni nič kaj "in place". Lepo naredi nov temp file, zafila disk, in krešne. :))

Zdej se bom lotil defragmentacije: https://mariadb.com/kb/en/defragmenting...
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

kunigunda ::

Ze arhitekturo imas zgreseno. Zakaj bi podvajal podatke v recordu, naredi kljuc s tremi fieldi (tisto kar imas sedaj v ID loceno z minusi), ce imas numericne,
jih daj v INT saj bo manjsi record in hitrejsi kljuc.
Pa 500mio zapisov je pomoje tudi za premislit ali so strukture ok.

HotBurek ::

Kaj pomeni "hitrejši ključ"?

A če ima:
- tabela_1 stolpec 'id', PRIMARY, tip INT(11), vrednosti od 0 do 9999999999,
- tabela_2 stolpec 'id', PRIMARY, tip VARCHAR(10), vrednosti od 0000000000 do 9999999999,

Da bo tabela_1 "hitrejša"? In če, pri čem bo hitrejša?

Kar ugibam je, da SQL server v prvem primeru rabi manj prostora na disku in v RAM-u, da postavi index in ga kešira.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

kunigunda ::

HotBurek je izjavil:

Kaj pomeni "hitrejši ključ"?

A če ima:
- tabela_1 stolpec 'id', PRIMARY, tip INT(11), vrednosti od 0 do 9999999999,
- tabela_2 stolpec 'id', PRIMARY, tip VARCHAR(10), vrednosti od 0000000000 do 9999999999,

Da bo tabela_1 "hitrejša"? In če, pri čem bo hitrejša?

Kar ugibam je, da SQL server v prvem primeru rabi manj prostora na disku in v RAM-u, da postavi index in ga kešira.


V prvi tabeli ti bo kljuc zavzel 4 byte, pri drugi 11. Krat 500mio rekordov pa zracuni razliko.
Kar se tice hitrosti bo posledicno v prvem primeru primerjal longint, v drugem pa string vsak znak posebi. Razlika v hitrosti ni zdej nek big deal ni pa zanemarljivo.

no comment ::

Glede na to, da očitno gre zgolj za sintetični ključ, ki nima nobene druge funkcije kot pa da kuri plac na disku, je bolje, da je int ;)

Šalo na stran, malo razmisli ali je ta kolona sploh nujna ali pa enoličnost lahko zagotoviš tudi s kakšnim drugi podatkom ali sestavljenim ključem. Če po poljih, ki sestavljajo tak ključ tudi dosti iščeš, boš že itak moral imeti index na njih...


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[MariaDB] INSTERT INTO z vmesnimi commit-ti per n rows?

Oddelek: Programiranje
12582 (298) kunigunda
»

[MariaDB] Kako napisat SQL za top N by group?

Oddelek: Programiranje
11527 (338) kljuka13
»

Mariadb (InnoDB) istočasni insert v tabelo iz različnih procesov (strani: 1 2 )

Oddelek: Programiranje
877265 (3623) 2g00d4u
»

[MariaDB] Zakaj SQL enači "ab " z "ab" v WHERE pogoju?

Oddelek: Programiranje
101053 (638) DamijanD
»

[SQL] Referenca na parameter v proceduri

Oddelek: Programiranje
71367 (1080) Ahim

Več podobnih tem