Forum » Programiranje » [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:
Tej tabeli bi rad dodal nov stolpec shop_id, ter v ta stolpec shranil vrednost, ki "pride" iz vrednosti v stolpcu id:
Tabela ima 476,605,116 row-ov.
Kako se tega lotit, da bo zadeva zmerno hitro končnana?
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
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.
Č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:
In guess what. Diska zmanjka, preden konča. Krneki ...
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?
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
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:
Zdej pa udpdate, kjer bom nastavil vrednost 'shop_id' (generirana iz vrednosti 'id'). Lets see.
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
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 ::
No, tole je pa uporabna dokumentacija.
Ampak, kolikor sem bral, bo potrebno še preverit kak to v praksi funkcionira.
Ravnokar pognal:
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...
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
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.
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.
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
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
kunigunda ::
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...
Š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 ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [MariaDB] INSTERT INTO z vmesnimi commit-ti per n rows?Oddelek: Programiranje | 587 (303) | kunigunda |
» | [MariaDB] Kako napisat SQL za top N by group?Oddelek: Programiranje | 531 (342) | kljuka13 |
» | Mariadb (InnoDB) istočasni insert v tabelo iz različnih procesov (strani: 1 2 )Oddelek: Programiranje | 7335 (3693) | 2g00d4u |
» | [MariaDB] Zakaj SQL enači "ab " z "ab" v WHERE pogoju?Oddelek: Programiranje | 1061 (646) | DamijanD |
» | [SQL] Referenca na parameter v proceduriOddelek: Programiranje | 1384 (1097) | Ahim |