Sziasztok!
Adott egy 90.000 és egy 30.000 rekordos tábla, mindkettőben 4, max. 30 karakteres szöveges mező található.
Két mező vizsgálata alapján kellene a kisebb rekordos táblát a nagyobból kivonnom.
Hogyan tudnám ezt a legoptimálisabban megtenni?
(bontsam fel kisebb táblákra a kivonandót?)
Üdv:
Cseresznye
- 7810 megtekintés
Hozzászólások
Az left join bal oldalán a nagyobb rekordos tábla, jobb oldalán a kisebb és where feltételben a jobb oldali tábla elsődleges kulcsa NULL kell legyen, ha erre gondoltál.
-----------
"640GB sokmindenre elég"
- A hozzászóláshoz be kell jelentkezni
Olvastam errefelé pár hete, hogy a mysql lefekszik a subselectektől - nem tudom, mennyire igaz ez, és mennyire igaz ilyen, viszonylag kis rekordmennyiségnél, de csak-csak tennék egy próbát not exist in (subselect) formával, HA létezik index arra a két mezőre (különben meg legyártanám azt).
- A hozzászóláshoz be kell jelentkezni
nem vétek azt használni. tény hogy lassabb, élesben nagy terhelésnél tényleg halál, deha van ideje kivárni, miért ne...
- A hozzászóláshoz be kell jelentkezni
Köszönöm mindenkinek.
Pontosítok:
Nagyobb tábla: 78.000 rekord
Kisebb tábla: 35.000 rekord
mezők a két táblában: index (auto_increment), nev, iszam, helyseg, cim
Ehhez mit szóltok?
delete from nagyobb_tabla where nev in (select nev from kisebb_tabla ) and cim in (select cim from kisebb_tabla);
Ez így 2 óra 48 perc volt.
- A hozzászóláshoz be kell jelentkezni
Megint ott tartok, hogy nem tudom, a mysql eszi-e, de legközelebb tehetsz egy próbát a ... where (nev, cim ) in (select nev, cim ...) formával. Ha a subselectre olyan háklis, és ha ezt viszont tűri, akkor egy púppal kevesebb neki.
- A hozzászóláshoz be kell jelentkezni
Betoltam MSSQL alá a két táblát, változatlan lekérdezéssel kb. 2 sec volt ami mysql alatt 2 óra 48 perc.
Elég nehezen tudom elképezni, hogy ekkora különbség lenne a két rendszer között..
Úgy érzem valamit elcseszhettem.
Mindkettő Server 2008 alatt futott, az MSSQL ráadásul terhelés alatt, míg a MySQL éjszaka, zéró terheléssel.
- A hozzászóláshoz be kell jelentkezni
Egy EXPLAIN eredményének vizsgálata nem ártott volna azért...
--
Coding for fun. ;)
- A hozzászóláshoz be kell jelentkezni
Ilyen egyszerű feladatnál valószínűleg nem egyszerűsítem le a dolgot nagyon azzal, ha azt mondom, csak bufferpool (a.k.a. cache) és optimalizáló kérdése a teljesítmény.
Valószínűleg a mysql esetén a kettő együtt kihoz egy ilyen hosszú direkt olvasást és írást, míg az mssql pedig elintézi az egészet memóriában, aztán aszonkron ír, ahogy illik.
- A hozzászóláshoz be kell jelentkezni
nomeg mysql-ben a subquery elég új fícsör még.
- A hozzászóláshoz be kell jelentkezni
hát öööööö
Ez ugye törli az összes lehetséges név-cím párt ami előfordul a kissebb táblában!
Téhát ha van a nagy táblában Kovács János 100 különböző cimmel, akkor mindegyik törölve lesz függetlenül attól,
hogy hányszor / milyen cimmel szerepel K.J. a kistáblában.
- A hozzászóláshoz be kell jelentkezni
Köszi, a cél nem ez lenne.
Azokat kell törölnöm a nagyobbik táblából, amik egyező névvel és címmel szerepelnek a két táblában.
- A hozzászóláshoz be kell jelentkezni
http://hup.hu/node/117982?comments_per_page=9999#comment-1509492
?
itt van subquery nélküli minus móka.
- A hozzászóláshoz be kell jelentkezni
Ezt is teszteld:
DELETE nagyobb_tabla AS a FROM nagyobb_tabla AS a LEFT JOIN kisebb_tabla AS k ON k.nev=a.nev AND k.cim=a.cim WHERE k.id IS NOT NULL;
nev-cim egyezeseket nez, megfelelo indexekkel ilyen kis tablan ez is tizedmasodpercek korul lehet.
szerk: IS NULL helyett IS NOT NULL persze:)
- A hozzászóláshoz be kell jelentkezni
Köszönöm!
szerk: ezt a mysql szintaktikai hibával dobta
Tesztelgettem piciben, ez jónak tűnik:
delete nagyobb_tabla from nagyobb_tabla right JOIN kissebb_tabla ON (kisebb_tabla.nev=nagyobb_tabla.nev AND kisebb
_tabla.cim=nagyobb_tabla.cim) where nagyobb_tabla.id is not null;
(passz, hogy, hogy az elején miért kell kétszer a nagyobb_tabla)
Valamiért így is piszok lassú.
- A hozzászóláshoz be kell jelentkezni
Vannak bizonyos esetek, amikor a mysql nem tud használni indexet. Ilyen pl a subselect afaik. Viszont a joinnál tud (vagy ha nem akar, akkor force index).
-----------
"640GB sokmindenre elég"
- A hozzászóláshoz be kell jelentkezni
kivonás alatt a MINUS nevű sql fícsört érted? Ez segíthet implementálni:
http://www.bitbybit.dk/carsten/blog/?p=71
- A hozzászóláshoz be kell jelentkezni
Ezt pont nem SQL-ben csinálnám: a két táblát sorba rendezve kitolnám fájlba, a hosszabbon egy ciklus végig, az aktuális sorát összehasonlítani a rövidebb soraival addig, amíg a rövidebből vett sor kisebb vagy egyenlő vele. ha kisebb, kiírni, ha egyenlő eldobni, és jöhet a hosszabból a következő sor.
- A hozzászóláshoz be kell jelentkezni
Itt már tisztább a probléma: http://hup.hu/node/117982#comment-1510527 :D
- A hozzászóláshoz be kell jelentkezni
Azért zeller kolléga javaslata nem meg- és elvetendő.
$ for i in `seq -w 1 78000`; do echo "$i, nev$i, 1111, Seholse, cimcimcim$i"; done > nagy.lst
$ tail -35000 nagy.lst > kis.lst
$ time awk -F", " 'FILENAME=="kis.lst" {kis[$2,$3]=$0; next}; !kis[$2 SUBSEP $3] { print } ' kis.lst nagy.lst > maradek.lst
real 0m0.370s
user 0m0.348s
sys 0m0.020s
$ wc -l maradek.lst
43000 maradek.lst
- A hozzászóláshoz be kell jelentkezni
Valóban, megint előbb írtam mint ahogy gondolkoztam.
- A hozzászóláshoz be kell jelentkezni
Öné a hangszóró :)
- A hozzászóláshoz be kell jelentkezni