táblák kivonása (MySQL)

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

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"

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).

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.

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.

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.

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.

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:)

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ú.

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.

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