MySQL optimalizálás

Sziasztok!

Van egy feladatom, amiben CSV-kből kell kiolvassak adatokat, majd azokat különböző táblákba kell beírogatnom.
Első körben úgy képzeltem, hogy legenerálom a lekérdzéseket, amiket egy tömbben tárolok, majd végigmegyek a tömbbön és beszúrogatom a lekérdezéseket.
Mivel cirka 170e insert/update/delete az, ami zajlik, szeretném megkérdezni, hogy van-e valakinek tapasztalata abban, hogy érdemes-e - időnyerés céljából - úgy módosítani a szkriptemet, hogy:
X táblából passzoló adatok kitörlése után inserttel szúrom be a sorokat
(ez van most)
X táblából lekérek mindent, majd úgy módosítom a lekérdezéseket, hogy ahol kell, ott update-tel módosítom a dolgokat.
Magyarul:
Most 2 táblában úgy dolgozom, hogy a "nekem izgalmas" sorokat törlöm (a sorban csak egy adat változik), majd beszúrom az új adatot tartalmazó sort. Érdemes lenne-e lekérdeznem, hogy szerepel-e ez a sor már a táblában és ha igen, akkor update-tel módosítom csak az adatot. Gyorsabb az update, mint az insert?

Előre is köszi:
hemu

Hozzászólások

szerintem mindenképp jobb az update, mint a delete + insert.
ugyanis:
1. valszeg kevesebb indexet fog érinteni
2. ha ugyanannyit is érint (gondolom PK-t azért nem), akkor is del+ins esetén úgy néz ki a történet, hogy: delete, index regen., insert, index regen
3. nem fog rommá töredezni a táblád (optimize table, ilyesmi)

persze a feladatleírás eléggé semmitmondó, szal elvileg bármi is lehet, célszerű lenne tesztelni a dolgot és aztán dönteni, de csodálkoznék, ha a del+ins jobban jönne ki.

x

szerk: "X táblából lekérek mindent, majd úgy módosítom a lekérdezéseket, hogy ahol kell, ott update-tel módosítom a dolgokat."
ez itt nagyon furcsa. az sql nem arra van kitalálva, hogy kiszedek mindent, mókolok rajta majd visszatöltöm. persze lehet ilyet csinálni, csak baromság. nem ismerem a feladatot, de lehet, hogy át kellene beszélned valami hozzáértővel azt, amit csinálni akarsz.

Pontosan az ilyenek miatt kell megfelelő kulcsokat/indexeket/unique-okat használni a táblán, és utána ott van MySQL-ben a:

INSERT ... INTO ... VALUES ... ON DUPLICATE KEY UPDATE ...
ld. http://dev.mysql.com/doc/refman/5.0/en/insert.html

vagy a

REPLCAE INTO [ DELAYED ]
http://dev.mysql.com/doc/refman/5.0/en/replace.html

A delete+insert nagyon-nagyon szélső esetektől eltekintve mindenképpen nagyságrenddel lassabb lesz.

A töredezéstől nem érdemes félni, a DBE feladata azt elkerülni, javítani. Persze a jó kulcsokat mindig neked kell megadni.

Ha nagyon pro akarsz lenni, akkor még tudom ajánlani az időszerűsítés algoritmusát:

- rendezed mind a két halmazt
- veszel mindkettőből egyet-egyet
- összehasonlítod az aktuális pár kulcsait, három lehetőség van: kisebb->be kell szúrni, megegyezik->update, nagyobb->törölni kell
- lépteted a párból azt, amit feldolgoztál
- ha mindkettő halmaz elfogyott, vége

--
The Net is indeed vast and infinite...
http://gablog.eu

Sziasztok!

Van 1 gep amin fut egy MYSQL amiben van egy adatbazis aminek a merete:
kb 5,5 GB es kb 50.000 tablabol all.
Ami mostansag elofordult hogy a gep megallt swap elfogyassal,meg ha az adatbazist eppen lekerdezik akkor az osszes szolgaltatas iszonytosan lelasssul...
Szoval azt tudom, hogy korlatozni kene,de mit es hol?
Hogyan alljak neki?

Elore is koszonom.
Pike.Killer

Hát ha korlátozni akarsz, akkor lejjebb veheted a memória beállításokat a my.cnf-ben. De ettől nem lesz jobb, ha egy túlterhelt rendszert korlátozol, akkor el tudod kerülni a kifagyásokat, de csak még kevesebb klienst fog tudni még lassabban kiszolgálni.

Több vas, és a lekérdezések ill. a kliensek logikájának optimalizálása az amivel tudsz gyorsulást elérni. Esetleg a fölös táblák/sorok kitakarításával.

--
The Net is indeed vast and infinite...
http://gablog.eu

my.cnf-ben ezek vannak
"
max_allowed_packet = 1M
max_allowed_packet = 16M
key_buffer = 8M
sort_buffer_size = 8M
key_buffer = 8M
sort_buffer_size = 8M
key_buffer = 16K
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K"

Top:
Mem: 163M Active, 54M Inact, 175M Wired, 12M Cache, 111M Buf, 587M Free
Swap: 2048M Total, 432M Used, 1616M Free, 21% Inuse

Log uzenet:
Jun 27 12:45:19 SERVERNAME kernel: swap_pager_getswapspace(16): failed
Jun 27 12:45:19 SERVERNAME kernel: swap_pager_getswapspace(8): failed
Jun 27 12:45:19 SERVERNAME kernel: swap_pager_getswapspace(12): failed
Jun 27 12:45:19 SERVERNAME kernel: swap_pager_getswapspace(16): failed
Jun 27 12:45:19 SERVERNAME kernel: swap_pager_getswapspace(12): failed

Hat ha ezek alapjan tudsz valamit mondani..

mysqlperformanceblog.com rol szedd le a perconba buildeket

és

thread_stack = 200K
thread_cache_size = 8

join_buffer_size = 2M
read_buffer_size = 4M
read_rnd_buffer_size = 16M
sort_buffer_size = 4M
myisam_sort_buffer_size = 128M
key_buffer = 384M
query_cache_limit = 1M
query_cache_size = 32M
#PERCONA SPECIFIC
innodb_buffer_pool_size = 2G
innodb_flush_log_at_trx_commit = 0
innodb_thread_concurrency = 0
innodb_file_per_table = 1
innodb_status_file = 0

innodb_io_capacity = 1000
innodb_write_io_threads = 16
innodb_read_io_threads = 16
innodb_flush_method = O_DIRECT
innodb_adaptive_checkpoint = 1

ez 8giga ram, 2gb db, masodpercenkent olyan 2-300 q
--
--ha magyar MAC-et akarsz--

myisam_sort_buffer_size = 128M

Ez nagyon lekerdezesfuggo, de alapjaban veve rossz otlet. A sort buffer egy per session parameter, es a sort buffer mindig lefoglalodik, amikor egy order by-os lekerdezes nem covering indexbol szolgalodik ki. Szoval 10 order by-os query mar 1 gb memoria. Meg kell vizsgalni, hogy mekkora a dataset, amit sortolni fogsz, es ennek megfeleloen lefoglalni, ennek a tulmeretezesevel is konnyen el lehet swappeltetni a gepet. InnoDB-nel, a sort buffer meret es hasonlok nem percona specifikusak.

innodb_flush_log_at_trx_commit = 0
Szinten rossz otlet. Ezzel gondolom azt akarod elerni, hogy az irasok felgyorsuljanak azaltal, hogy egy adott tranzakciora mar akkor mondja, hogy sikeresen commitelve van, hogyha mar a log bufferben van, de meg nincs kint disken. Az alapbeallitas ennel 1, ami ezt kikapcsolja, ilyenkor az InnoDB ACID compliant. A 2-nek en nem latom igazabol hatranyat a 0-hoz kepest, csak elonyet, de ezt nezd meg. Es remlik, mintha a perconasok is ezen a velemenyen lennenek.

Eredeti post:
Hogyha csv-bol akarsz adatbazisba tenni adatokat, akkor nezd meg a load data-t, pontosan erre valo, es nagyon gyors. On duplicate key es hasonlok mukodnek load data-val is.

Mondjuk ezt szerettem volna elkerulni. Viszont azt kene tudnom,hogy amig ezet megteszem , mit lehet vele kezdeni ,hogy a gep ne haljon le. Mivel ilyenkor sajnos csak a reset segit az meg, hat eleg maceras.
Szerintetek ha a swap pariciot nevelem az segit-e valamit a helyezeten mi a memoria bovites megtortenik?

szia, csak érdeklődés képen mondd már el légyszi' mi az a feladat amit ~50.000 táblával lehet megoldani,
ugyanis még sohasem találkoztam ilyennel, és el sem tudom képzelni.
- tudom, ez engem jellemez. :(
előre is köszi.

--
"Megtanultam a zenét, de nem csináltam, s azóta tudással, de irigység nélkül hallgatom.
Megtanultam egy sereg tudományt, mesterséget és művészetet, értek hozzájuk, de nem csinálom, s így érdektelenül tudom azokat élvezni. "
Hamvas Béla

Pedig erre kerdezz ra, mert a db szerver meretezesehez ez _nagyon_ fontos parameter. Ha lehet, akciozzal, hogy ez a szam drasztikusan csokkenjen, mert _nincs_ olyan feladat, amihez egy ekkora gep eleg _es_ 50k tabla kell hozza. A programozotok nagyon nem ert a szakmajahoz.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Ez sem teljesen kerek. Ha 1 tabla lenne 50k sorral, akkor az 5GiB adatbazis az nagyjabol 100kB meretu sorokat jelentene, a MySQL maximalis 64kiB sormeretehez kepest.
Persze az indexek is viszik a helyet, de itt mindenkepp valami gaz van a DB tervezessel..

--
"ne támogasd az erdők kiírtását mozijeggyel, töltsd le a netről!" - killllll, asva.info