Van egy főtábla (`employees`
):
emp_no int(11)
birth_date date
first_name varchar(14)
last_name varchar(16)
gender enum('M','F')
hire_date date
Egy segédtábla (`titles`
):
emp_no int(11)
title varchar(50)
from_date date
to_date date NULL
És egy másik segédtábla (`salaries`
):
emp_no int(11)
salary int(11)
from_date date
to_date date
Mind a két segédtáblában foreign key az `emp_no`
. A szűrés és lekérdezés megy így is:
SELECT `employees`.*, `titles`.`title`, `salaries`.`salary`
FROM `employees`
LEFT JOIN `titles` ON
(`titles`.`emp_no` = `employees`.`emp_no`) AND
(`titles`.`from_date` = (SELECT MAX(`from_date`) FROM `titles` WHERE `titles`.`emp_no` = `employees`.`emp_no`))
LEFT JOIN `salaries` ON
(`salaries`.`emp_no` = `employees`.`emp_no`) AND
(`salaries`.`from_date` = (SELECT MAX(`from_date`) FROM `salaries` WHERE `salaries`.`emp_no` = `employees`.`emp_no`))
WHERE (`titles`.`title`='Staff') AND (`salaries`.`salary`>='120000')
LIMIT 0, 20
De ez így nagyon lassú, 4-5 másodperceket kotorászik, pedig alig hárommillió rekord van a `salaries`
-ben, négyszázezer a `titles`
-ben és háromszázezer az `employees`
-ben. (Ha pedig még sorrendezés is kerül bele, akkor aztán több, mint 10 másodperc...)
Próbáltam így is
SELECT `employees`.*, `titles`.`title`, `salaries`.`salary`
FROM `employees`
LEFT JOIN `titles` ON
(`titles`.`emp_no` = `employees`.`emp_no`) AND
(`titles`.`from_date` = (SELECT MAX(`from_date`) FROM `titles` WHERE `titles`.`emp_no` = `employees`.`emp_no`))
LEFT JOIN `salaries` ON
(`salaries`.`emp_no` = `employees`.`emp_no`) AND
(`salaries`.`from_date` = (SELECT MAX(`from_date`) FROM `salaries` WHERE `salaries`.`emp_no` = `employees`.`emp_no`))
WHERE `employees`.`emp_no` IN
(
SELECT `ut`.`emp_no` FROM
(
(SELECT `titles`.`emp_no` FROM `titles` WHERE `titles`.`title`='Staff')
UNION
(SELECT `salaries`.`emp_no` FROM `salaries` WHERE `salaries`.`salary`>='100000')
) `ut`
)
LIMIT 0, 20
viszont így nem jó a végeredmény, rossz értékek jelennek meg a szűrt oszlopokban. Próbáltam úgy is, hogy először megszűröm az eredményt és aztán JOIN-olok
SELECT `employees`.*, `titles`.`title`, `salaries`.`salary` FROM
(
SELECT * FROM `employees`
WHERE `employees`.`emp_no` IN
(
SELECT `ut`.`emp_no` FROM
(
(SELECT `titles`.`emp_no` FROM `titles` WHERE `titles`.`title`='Staff')
UNION
(SELECT `salaries`.`emp_no` FROM `salaries` WHERE `salaries`.`salary`>='100000')
) `ut`
)
) AS `employees`
LEFT JOIN `titles` ON
(`titles`.`emp_no` = `employees`.`emp_no`) AND
(`titles`.`from_date` = (SELECT MAX(`from_date`) FROM `titles` WHERE `titles`.`emp_no` = `employees`.`emp_no`))
LEFT JOIN `salaries` ON
(`salaries`.`emp_no` = `employees`.`emp_no`) AND
(`salaries`.`from_date` = (SELECT MAX(`from_date`) FROM `salaries` WHERE `salaries`.`emp_no` = `employees`.`emp_no`))
LIMIT 0, 20
de dettó rossz adatok jöttek ki.
Sajnos már vagy 8-10 év óta nem foglalkoztam SQL-lel a sima SELECT
/INSERT
/UPDATE
/DELETE
szinten túl, így keresni is hiába kerestem, mert igazából nem tudom, hogy mit keressek.
Hogyan lehet ezt tisztességesen megcsinálni, hogy előbb leválogatja a két segédtáblából azokat a sorokat, amik érintettek és csak azokat kérje le a főtáblából, amik csatolhatóak?
Hozzászólások
MySQL-t
sajnoshál' Istennek sosem kellett élesben használnom, de amik dialektustól függetlenül eszembe jutnak (csak a helyes eredményt mutató query-t megnézve):1) Én megpróbálnám, hogy nem az egész táblával JOIN-olok, hanem egy subquery-vel, ami eleve csak azokat tölti be a két segédtáblából, amire szükség van
2) Ha van ráhatásod a DB struktúrára, akkor megfontolhatod a DB-t denormalizálva a current_title és current_salary mezőket letárolni az employee táblában. (Ofc erről az adatbázis kliensnek is tudnia kell, vagy DB oldalon csinálod meg, hogy ott legyen a cache)
3) from_date ha nincs indexelve, az is megér egy próbát
Imho itt a bottleneck az egyes pont: a hárommillió soros tábla minden soránál kétszer nyálazod végig mindkét segédtáblát ahelyett, hogy egyszer csinálnád meg a segédtáblás lekérdezést (emp_no, title, MAX(from_date)), és onnan szednéd ki, ami kell.
szerk: aztán persze ki tudja, nálam eddig kb. 70% T-SQL, 29% PL/SQL, 1% egyéb :)
1) Így gondoltad?
Mert így kb. a 2x-esére gyorsult és a sorrendezéssel sem sokkal lassabb, így kb. 1-2-3 sec, amíg bejön. Köszi a tippet.
2) Nincsen. Ez most localban van, de ahol majd tesztelni fogják, ott az a DB felállás lesz, ahogy most van. Amúgy nekem is az első gondolatom az lett volna, hogy csinálok egy redundáns tárolótáblát, a pillanatnyi értékekkel, dehát ez itt nem játszik.
3) De az indexelve van. A
`salary`
nincs és a`title`
sem, de utóbbira már nem is tudnékFULLTEXT
-et nyomni, mert az InnoDB csak kreáláskor engedi, a kreálást pedig nem én végzem: importálni kell. :( A`salary`
-ra rakhatnék, de ld. 2)-es pont.Valószínűleg igazad van, mert így jelentősen gyorsabb lett. Még majd bütykölöm, hátha bírok rajta valamit csinálni, de a lényeg, amit a topiccímben is feltettem, az előszűrés már megvan, úgyhogy, thx again.
Oldschool Computer - http://oscomp.hu
Aha
Nem fulltextre gondoltam, hanem a from_date mezőkre, hogy hamarabb megtalálja a legutolsó érvényes sort.
Az indexelve van.
Oldschool Computer - http://oscomp.hu
Viszont, ha meg nincs szűrés, akkor ezzel az új egközelítéssel az eddigi 1 sec-ről 5 sec-re emelkedik a várakozási idő... Szűrve 2x olyan gyors, szűretlenül 5x olyan lassú.
Oldschool Computer - http://oscomp.hu
join-hoz jó, hogy van a dátumon index, de a fizetés és title szerinti szűrésen úgy érzem, hogy segítene egy salary index és egy title index. Bár nem tudom, a mysql hogy csinálja.
disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.
Lehet, hogy jól jönne rájuk, bár végül is nélkülük is megoldódott.
Oldschool Computer - http://oscomp.hu
indexek a használt mezőkön?
Ld. a geleinek adott válasz 2)-es és 3)-as pontját: a lekért
`titles`
és`salary`
mezőkön nincsen, de a saját localhostos importomban hiába indexelek rommá mindent.Oldschool Computer - http://oscomp.hu
Gondolom egy program fogja lekérni ezt rendszeresen, másképpen nem lenne érdekes annyira a válaszidő. Lehet valahogy végrehajtási tervet kérni az adatbázistól? Azt sem tartom elképzelhetetlennek, hogy ez ennyi ideig tart normálisan is. Nagyjából 150MB-t kell végignyálazni, ha nem tud értelmesen indexet használni. Nyilván a végrehajtási terven múlik, de a DB nem tudhatja megsaccolni, hogy éppenséggel melyik terv lesz a jó? Sőt, te sem feltétlenül tudod, mert nem mindegy, hogy a kisfizetésű vezérigazgatókat keressük (ekkor a vezérigazgatókra érdemes először szűrni) , vagy a nagyfizetésű átlagdlgozóra (ilyenkor a nagy fizetésre érdemes először szűrni). Tehát adatfüggő lesz, hogy melyik stratégia a jobb.
Egy megoldás lehet az, hogy megsejted, hogy milyen sorrendbéli végrehajtás a legjobb, és azt "kézzel leprogramozod". Tehát például először lekérdezed a 120 ezer feletti fizetésűeket. Aztán ezekkel az azonosítókkal az ő title-jüket. Végül hozzácsattintod a nevüket. Nem a legszebb megoldás, de működhet.
Ha lekérdezésre kell optimalizálni, akkor én is denormalizálnám azt a részt, ami alapján a lekérdezés megy. A salary és a title változásokat például egyetlen táblában lehetne követni. Akkor nem kellene join ahhoz, hogy egyfajta title- fizetés kombinációt megtaláljunk. Persze így hirtelen nagyra nőne a tábla a varchar(50) miatt, de a titlék száma jó esetben igencsak korlátos lesz, ezeknek lehet adni egy számot. Persze az is kapcsolótábla, de pici, és a lekérdezés lényege már int azonosítókon futna le. Tehát így:
Erre ha rádobsz egy összetett tree alapú indexet titeid+salary sorrendben, akkor a lekérdezésed eredményei kb azonnal ki fognak folyni a rendszerből.
Egy másik megoldás lehet, hogy úgynevezett materializált nézetet hozol létre, amennyiben a lekérdezésnek van olyan része, ami ésszerűen cache-elhető. (https://en.wikipedia.org/wiki/Materialized_view) De ezt nem tudom van-e MySql-ben, meg hogy alkalmazható-e az esetedben. Például a salary-title joint lehetne materializált nézetben tartani. Vagy akár mindhárom tábla joinját current date-re vonatkozóan.
Ja, és a lényeg:
Már itt rossz a sémád! Mi ez a kirekesztés????4!!?!? :-)
Egy website kéri le. Végrehajtási terv alatt mit értesz, az explaint?
Mir értesz "kézzel leprogramozás" alatt? Olyannal próbálkoztam, hogy leszűröm a
`salaries`
és`titles`
táblát és csak azokat az ID-kat kérem le, amik kellenek, de rossz eredményeket adott, az OP-ban ott a query.Arra én is gondoltam, hogy csinálok egy közös táblát, amiből kérdezget, aztán ott is update-elgeti, amit kell, csak nem tudom, hogy azt el fogják-e fogadni, bár ez csak az egyik gond. A nagyobbik, hogy próbálkoztam olyannal, hogy
Csak ez 11076 sor felett
"Error in query (1062): Duplicate entry '21076' for key 'PRIMARY'"
hibaüzenetet dobott. Fel nem fogom miért, hiszen a beszúrandó`emp_no`
nem ismétlődik sehol, más PRIMARY KEY meg nincs ebben a táblában...Egyébként a teszt DB itt elérhető: https://github.com/datacharmer/test_db
Materializált nézet MySQL-ben nincs.
Majd írok a MySQL-eseknek, hogy tegyenek be kettő db. 256-bites floatot helyette és akkor két csúszkán lehet beállítani, hogy ki mennyire M, meg F. :P Bár inkább nem adnék nekik ötleteket...
Oldschool Computer - http://oscomp.hu
A kézzel leprogramozást úgy értem, hogy lefuttatod az alqueryt és annak az eredményét kiveszed resultsetként, majd visszafeedeled a következő query-be úgy, hogy az értékeket sorba beleírod a lekérő SQL-be. Alapvetően hülyeség ilyet csinálni, de mégis néha érdemes, például mert így látjuk mi mennyi ideig tart önmagában. Bár aki ismeri az adatbázisát, az valószínűleg abból is ki tudja nyerni a részeredményeket.
További ötlet lehet, hogy a max date bejegyzést a salary és a title táblában is egy boolean-nal megjelölöd. Így nem kell ezeket mindig kinyálazni, egyből rendelkezésre áll - pláne, ha be van indexelve ez a flag. Nyilván a frissítésekkor ezt a flaget kezelni kell. Az indexelésnél lényeges, hogy ne egy adat alapján legyen, hanem a teljes halmazon, amire a lekérdezés vonatkozik. Ugyanis ha egy-egy oszlopon van index, és kettőre vonatkozik a kérdés, akkor még mindig két eredményt őssze kell fésülni. Azonban ha például van egy (latest_entry, salary) összetett indexed, akkor egy where latest_entry and salary>10000 kérdés teljesen indexből kiszolgálható.
A Duplicate entry fogas kérdés. Akármelyik al-lekérdezésnek ha több értéke van véletlenül, az okozhatja. Például a department, ha a dept_no véletlenül nem zárja ki az ismétlést. Vagy ha a date alapú lekérdezésben van két egyforma dátum (ez valószínűbb) és az duplikált sort okoz. Nem logikus, hogy valakinek egyazon dátumon két különböző címe van, de ez a tipikus, hogy a való életbeli adatbázisok tele vannak ilyenekkel. Pláne amiket emberek töltenek fel! Úgy kell megfogalmazni a query-ket, hogy ezek ne okozhassanak bajt! Tesztelni úgy lehet, hogy a lekérdezést lefuttatod akár kulcs nélküli táblába, majd abban keresel duplikátumot valahogy így: https://chartio.com/learn/databases/how-to-find-duplicate-values-in-a-s…
Amúgy én sem vagyok egy SQL mágus, a tananyagot elég jól megtanultam, az adatszerkezetek a véremben vannak, de ritkán használom, és amikor kell, akkor folyton keresnem kell, hogy mit hogy is kell leírni SQL-ben.
> A kézzel leprogramozást úgy értem, hogy lefuttatod az alqueryt és annak az eredményét kiveszed resultsetként, majd visszafeedeled a következő query-be úgy, hogy az értékeket sorba beleírod a lekérő SQL-be.
És ezt hogyan csináljam? Temporary tables-t már próbáltam, de csak még jobban belassított mindent. Olyat is próbáltam, hogy leszűröm a két segédtáblát és az ID-ket használom a fő query szűrésére (ez az OP-ban is benne volt, ez a két query), de rossz végeredményt kaptam.
> További ötlet lehet, hogy a max date bejegyzést a salary és a title táblában is egy boolean-nal megjelölöd. Így nem kell ezeket mindig kinyálazni, egyből rendelkezésre áll - pláne, ha be van indexelve ez a flag.
De ezzel ugyanott vagyok, ahol most, mert a
`from_date`
is indexelve van.> Az indexelésnél lényeges, hogy ne egy adat alapján legyen, hanem a teljes halmazon, amire a lekérdezés vonatkozik. Ugyanis ha egy-egy oszlopon van index, és kettőre vonatkozik a kérdés, akkor még mindig két eredményt őssze kell fésülni. Azonban ha például van egy (latest_entry, salary) összetett indexed, akkor egy where latest_entry and salary>10000 kérdés teljesen indexből kiszolgálható.
Ebben lehet, hogy igazad van, csak épp nem piszkálhatok hozzá a szerkezethez.
> A Duplicate entry fogas kérdés. Akármelyik al-lekérdezésnek ha több értéke van véletlenül, az okozhatja. Például a department, ha a dept_no véletlenül nem zárja ki az ismétlést. Vagy ha a date alapú lekérdezésben van két egyforma dátum (ez valószínűbb) és az duplikált sort okoz. Nem logikus, hogy valakinek egyazon dátumon két különböző címe van, de ez a tipikus, hogy a való életbeli adatbázisok tele vannak ilyenekkel. Pláne amiket emberek töltenek fel! Úgy kell megfogalmazni a query-ket, hogy ezek ne okozhassanak bajt! Tesztelni úgy lehet, hogy a lekérdezést lefuttatod akár kulcs nélküli táblába, majd abban keresel duplikátumot valahogy így: https://chartio.com/learn/databases/how-to-find-duplicate-values-in-a-s…
Köszi az ötletet, ezt kipróbálom. (Mondjuk itt ezen a "cache" táblán, amit csináltam, egyedül a PRIMARY KEY-en nem lehet ismétlődés és azon nincs is.)
Oldschool Computer - http://oscomp.hu
> És ezt hogyan csináljam?
Ilyesmi:
SQL:
Programban a resultsettel ezt csinálod:
És így tovább. Tehát az al-lekérés eredményét áthajtod a programon. Ez szinte mindig antipattern, nem is végleges megoldásnak javaslom én sem, hanem azért hogy meg tudd mérni, hogy melyik része meddig tart, és akkor azon tudsz gondolkodni, hogy mit lehetne optimalizálni.
Abban a szélsőséges esetben viszont, ha az adatbázis által megálmodott lekérdezés tervnél egyértelműen okosabbat is ki tudsz találni, akkor akár még jobb is lehet egy ilyen megoldás. Hasonlóképpen, ha az al-lekérések eredményeit cache-eled egy korábbi lekérdezésből, vagy valami ilyesmi, akkor is ésszerű lehet ilyet csinálni.
> Ebben lehet, hogy igazad van, csak épp nem piszkálhatok hozzá a szerkezethez.
Ha nem lehet hozzányúlni a szerkezethez, akkor simán lehet, hogy ezek a lekérdezési idők nagyjából kiadják a rendszer lehetőségeit. Gondold meg, hogy ha nincsen célirányos index, akkor a teljes adatmennyiséget végig kell nyálazni. 150 mega (a legnagyobb tábla becsült mérete) nem annyira sok, de ha arra a szűrésre sok pozitív találat van, akkor nagyon sok kulcsot kell lekérni a másik táblából, ami minden esetben egy fában keresés lesz. Hozzávéve, hogy esetleg a cache is rosszul használódik akár még ki is jöhet, hogy ezen az adatszerkezeten ez ennyi és kész. Én leprogramoznám ugyanezt a lekérést Java-ban a megfelelő indexeket TreeMap-ekbe téve, és ha hasonló idők jönnek ki, akkor ez ennyi és kész. (Mármint csak akkor csinálnék ilyet, ha nagyon fontos lenne az egész, és ráadásul jobb ötletem sem lenne. Benchmarknak, hogy mit lehet kihozni a vasból. Hasonlóan a megfelelő indexeket is felvenném még akkor is, ha a végső produktba valamiért nem lehet beletenni ezeket: szintén benchmarknak.)
> Végrehajtási terv alatt mit értesz, az explaint?
Azt hiszem úgy hívják. Olyanok vannak benne, hogy először ehhez az indexhez fogok nyúlni, és ezeket a feltételeket tudom szűrni vele. Utána az eredményt ezzel a másik táblával összejoinolom. És így tovább.
Adatbázisok tárgyból mi annó úgy tanultuk, hogy az SQL egy leíró nyelv, amivel ilyen elméleti konstrukciókat lehet leírni, amikkel deklaráljuk, hogy mit akarunk látni, de egyáltalán nem tudunk általa a lekérdezés végrehajtásának mikéntjére hatni. Legalábbis ez az elv. Az adatbázis a lekérdezésből egy absztrakt adatszerkezetet csinál, amit aztán transzformálgat, ahogy neki tetszik. Tehát két ekvivalens lekérdezésnek ha teljesen más is a formája, akkor is ugyanarra a lekérdezési tervre fordul le többnyire. Hasonlóan az optimalizáló fordítókhoz, illetve tulajdonképpen ez is az. Az olyanok viszont már számítanak, hogy a feltételeket hogyan fogalmazzuk meg, például egy indokolatlan egyenlőség helyett "like" használat le tudja rontani a teljesítményt és hasonlók.
Na most a végrehajtási terv az már egy imperatív dolog, és ha tudod, hogy mekkorák a részeredmények, akkor az alapján már lehet futásidőt is becsülni. Illetve a részlet lekéréseket külön-külön is tudod futtatni, tudod mérni (sőt, szerintem van ilyen feature-e az explain-nek, hogy a mérési eredményeket is beleírja). És akkor látszani fog, hogy mi lassú, hol megy el az idő. Ha van benne négyzetes skálázódás, illetve olyan, hogy a szűrést a rossz oldalon kezdi, akkor azokon lehet gondolkodni, hogy hogy lehet kikerülni. Ha meg nincs, akkor ennyit tud a vas, és mégiscsak a tárolási szerkezetet meg kell változtatni.
> Ilyesmi:
Hát ez ugyanaz pepitában, amit én csináltam az OP-ban... Rossz eredményeket adott. Persze lehet, hogy én írtam meg a lekérést rosszul.
> Ha nem lehet hozzányúlni a szerkezethez, akkor simán lehet, hogy ezek a lekérdezési idők nagyjából kiadják a rendszer lehetőségeit.
Közben hunludvig kolléga javaslata nyomán kiderült, hogy egyáltalán nem. Jól sejtettem én, hogy ennek sokkal gyorsabban kellene mennie, csak nem tudtam, hol fogjam meg.
> Azt hiszem úgy hívják. Olyanok vannak benne, hogy először ehhez az indexhez fogok nyúlni, és ezeket a feltételeket tudom szűrni vele. Utána az eredményt ezzel a másik táblával összejoinolom. És így tovább.
Oké, lecsekkoltam, az átírt query a
`salary`
-ra sorrendezve így néz ki:És itt az explain:
Asszem itt inkább azzal lesz a baj, hogy a sorrendezésbe belezavar az a csomó olyan entry, ami a dátumok alapján már érvénytelen. Vagy nem, mert a sorrendezésnél már minden le van szűrve és oda van csatolva?
Oldschool Computer - http://oscomp.hu
Ránéztél az adatra is?
SELECT * FROM dept_emp WHERE emp_no = 21076;
21076 d004 1993-07-25 1993-08-04
21076 d005 1993-07-25 1993-07-25
Itt az összes "duplikáció":
SELECT * FROM dept_emp WHERE emp_no IN (21076,37429,44683,49509,64098,69836,82648,91899,109363,206466,219624,228322,246188,282558,285052,285338,290639,433010,433358,435075,435183,440659,452212,468620,469544,475919,491049,496147,499964);
Tehát azért van duplikáció, mert adott kezdődátummal több department is fel van sorolva (gyk, egy napon belül lett új department-je).
Hopp, köszi... Akkor úgy néz ki, először be kell importálni a fő táblát aztán egyesével ráupdate-elni a három másikat.
Oldschool Computer - http://oscomp.hu
Azt jól látom, hogy a to_date alapból NULL és ha van változás (új bejegyzés), akkor kap értéket?
Ez esetben én a to_date = NULL-ra keresnék nem a max(from_date)-re.
Nem egészen. A
`to_date`
lehetNULL
, de egyetlen sorban sem az, így`to_date` IS NULL
-ra nincs értelme vizsgálni.Oldschool Computer - http://oscomp.hu
ahogy latom a test_db-kben 9999-01-01 van a "null" van, en erre szurnek
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
Csak rosszabb lenne, ugyanis a
`to_date`
-en nincs index, azonfelül a tartalma irreleváns, mert a legutolsó title, salary és department a legutolsó`from_date`
alapján választódik ki, az érdektelen, hogy még él-e (9999-01-01), vagy befejeződött (egyéb dátum).Oldschool Computer - http://oscomp.hu
Akkor mi a célja a mezőnek?
Mert, ha használnád, akkor kb 1000x-es gyorsulást érnél el.
Az, hogy mutatja, hogy él-e még az aktuális cím vagy fizetés...de amúgy ez a MySQL egyik tesztadatbázisa, nem én terveztem.
Hogy érnék el vele 1000x-es gyorsulást?
MAX(`from_date`)
per kopf (azaz per`emp_no`
) egy darab van,`to_date`='9999-01-01'
meg vagy egy, vagy egy sem, ha az utolsó aktuális érték befejezett, ennek megfelelően, ha leszűröm, hogy ahol`to_date`='9999-01-01'
, azt adja ki, akkor egy csomó embernélNULL
-t fog visszaadni, mert az utolsó megkezdett érték időszaka már be van fejezve nekik. Azonfelül ellentétben a`from_date`
-tel, ez nincs indexelve.Oldschool Computer - http://oscomp.hu
jo, hat aszittem hogy csak az 'aktiv' munkak fizetesere vagy kivancsi. annak mi ertelme hogy jozsika 10 eve akarmikent 10$-t keresett, de azota mar nem is dolgozik a cegnel?
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
Semmi, de nem én találtam ki a szerkezetet.
Oldschool Computer - http://oscomp.hu
Ez valami egyetemi feladat?
Nem.
Oldschool Computer - http://oscomp.hu
Dettó
Max egy fv ami lescanneli kb a full tablát. Is null egy reláció ami meg nem.
Kb tabla1*tabla1 vs. 2^n = legnagyobb tabla
a különbség.
Vagyis 1m rekordnál 1.000.000^2 vs 20 a kulobseg, mert 2^20 > 1.000.000
De nincs
NULL
benne. Csak lehetNULL
, de egy darab sincs benne; ami nincs belőve az mind'9999-01-01'
. Azonfelül a`from_date`
indexelve van, nem kell az egész táblát végigscannelnie, csak az indexeket, a`to_date`
pedig nincs, ahhoz viszont pesszimális esetben végig kell, ha a legvégén van, vagy egyáltalán nincs. A listában feltüntetni pedig az utolsó érvényes címet, vagy fizetést kell. Ha az utolsó indulódátum helyett leszűröm, hogy`to_date` != '9999-01-01'
, akkor tele leszNULL
értékekkel, ahol már le van zárva.Oldschool Computer - http://oscomp.hu
Szerencsésebb lenne nem tagadással keresni.
Sorry, fáradt vagyok már.
Szóval, ha az utolsó indulódátum helyett leszűröm, hogy
`to_date` = '9999-01-01'
, akkor tele leszNULL
értékekkel, ahol már le van zárva.Oldschool Computer - http://oscomp.hu
Igazából nem értem mit szeretnél. Azt hittem valós a probléma, mert ha az lenne vélelmezem akkor megoldás lenne amit írtunk, igaz cserébe nem kapnád meg a befejezett és nem aktuális eredményeket, míg a max fv-vel igen.
Már átírtam. Viszont így egyáltalán nem kapom meg azt a sort, ha be van fejezve.
Oldschool Computer - http://oscomp.hu
Én az employeet left jointolnam és a főtáblám az lenne amelyikben a legnagyobbat vágom.
Ha jól sejtem az pedig a fizetés.
És az miért oldaná meg az eltűnő sorok problémáját?
Oldschool Computer - http://oscomp.hu
Ahhoz nincs köze. A sebességhez viszont lehet. Valahogy a max fv-t hanyagolni kellene. Nem tudom gyorsít-e de ha elöször a konstansra szűrsz majd utána max fv, az is gyorsíthat.
A szűrési sebesség már megoldódott. hunludvig kolléga tippje után minden begyorsult és <1s alatt jön be, a
salary
-ra való rendezést leszámítva.Oldschool Computer - http://oscomp.hu
/* Sorok megjelenítése 0-19 (összesen 20, A lekérdezés 0.0032 másodpercig tartott.) */
Mi a feladat? Mire kell leszűrni, rendezni?
Rendezve:
/* Sorok megjelenítése 0-19 (összesen 20, A lekérdezés 0.0001 másodpercig tartott.) */
Általánosan, egy táblában kell megjeleníteni az adatokat, ami szűrhető és rendezhető. Már minden gyorsan megy, csak a fizetésre sorrendezve, ha sok sort talál, lassú.
Ez is az.
Update: "/* Sorok megjelenítése 0-19 (összesen 20, A lekérdezés 0.0001 másodpercig tartott.) */"
Persze, mert becache-eli, ha ugyanazokat az adatokat kéred le. Ha megváltoztatod, hogy mire szűrsz, vagy a
LIMIT
paramétereit, akkor 3-4 sec-ig tart.Oldschool Computer - http://oscomp.hu
Nehezen tudom elképzelni, hogy mitől lesz gyorsabb a rendezés. Engem is érdekelne.
Jahh. cache volt, benéztem. Biztosan duplaklikk ment.
Viszont, lehet nektek lesz igazatok; nem a sebesség miatt, (az eddig kb. ugyanaz), hanem azért, mert ha nem szűröm le, akkor, ha aznap több titulusváltás történt, akkor a
`from_date`
-ból több egyformaMAX
van, ami a listában duplikált sorokat jelent: az összes utolsó napi meg fog jelenni, a sor többi részét tekintve identikus adatokkal. Ez rosszabb, mint ha üres mezők lennének a lezárt entry-knél; azt lehet magyarázni épeszű indokkal, hogy nincs aktuális címe, fizetése, whatever, ezt meg nem.Oldschool Computer - http://oscomp.hu
Ez is igaz, bar ez bennem fel sem merült. Grat érte. Figyelmes voltál.
Thx.
Oldschool Computer - http://oscomp.hu
ki tudsz tenni valahova egy dumpot dummy adatokkal, hogy kicsit lehessen jatszani vele? en kivancsi vagyok!
Fentebb már adtam linket, ez a MySQL egyik publikus tesztadatbázisa: https://github.com/datacharmer/test_db
Oldschool Computer - http://oscomp.hu
SELECT `employees`.*, `titles`.`title`, `salaries`.`salary`
FROM `employees`
LEFT JOIN `titles` ON
(`titles`.`emp_no` = `employees`.`emp_no`)
LEFT JOIN `salaries` ON
(`salaries`.`emp_no` = `employees`.`emp_no`)
WHERE (`titles`.`title`='Staff') AND (`salaries`.`salary`>='120000')
AND `salaries`.`from_date` = (SELECT MAX(`from_date`) FROM `salaries` WHERE `salaries`.`emp_no` = `employees`.`emp_no`)
AND `titles`.`from_date` = (SELECT MAX(`from_date`) FROM `titles` WHERE `titles`.`emp_no` = `employees`.`emp_no`)
LIMIT 0, 20;
Ez nálam valamivel gyorsabban fut le.
Igen, így a szűrés villámgyorssá (<1s) vált, ezt nagyon köszi.
Csak sajnos a sorrendezés így 5-6 másodperc...Visszavonom: kizárólag a`salary`
-ra sorrendezve lassú. Asszem mindjárt egy index-szel fogom honorálni a dolgot. Update: Sajnos nem segített rajta sem az"ALTER TABLE `salaries` ADD INDEX `salary` (`salary`);"
, sem az"ALTER TABLE `salaries` ADD INDEX `emp_no_salary` (`emp_no`, `salary`);"
...Oldschool Computer - http://oscomp.hu
nekem segitett:
ez a salaries tabla:
De próbáld meg egy olyan halmazzal, aminek a szűrőfeltételei több eredményt hagynak, vagy próbáld meg szűrés nélkül:
Oldschool Computer - http://oscomp.hu
Rég foglalkoztam SQL-lel, mysql-lel meg soha.
A következők jutnak eszembe:
1) egyfelől el kell fogadni, hogy csak azért, mert az SQL tud valamit, egyáltalán nem biztos, hogy használható lesz sebességben.
2) meg kell nézni, hogy mit próbál csinálni. Akár úgy, hogy végiggondolod, akár úgy, hogy ha van rá lehetőség, hogy a használt eszközt megkérdezed, és az megmondja, hogy ezt megnézi ennyiszer, azt megnézi annyiszor, stb.
2.1) ha bárhol full table scan van, az nem jó. Főleg nem, ha sokszor végrehajtja az elemzés szerint. Szóval ha valami mező szerint szűrsz, nézd meg, hogy van-e rajta index.
3) Ha mindig a max(from_date) kell, és az összes többi sora annak a táblának felesleges, akkor én egyfelől simán készítenék két view-t (current_title, current_salary). Ha a dátum mezőn van index, akkor a view maga várhatóan nem fog gyorsítani a dolgon, viszont jóval egyszerűbb lesz az SQL query. Én, személy szerint kedvelem a könnyebben átlátható query-ket, bár tudom, hogy nem mindenki van így ezzel.
3.1) Nem tudom, hogy a mysql tud-e materialised view-t, ha igen, akkor ez gyorsabb lehet, mert míg a view-ból select esetén a view deklarálásakor megadott query-t lefuttatja újra, a materialised view az gyakorlatilag táblaként viselkedik, szóval ott már nincs újabb query futtatás. Persze ha a view valami faék egyszerű dolog, akkor a view query futtatása nem lesz lassabb, mint a materialised query-t egyszerűen végigolvasnia.
Ha materialised view-t nem tud a mysql, akkor készíthetsz magadnak egy vagy több segédtáblát (amit triggerekkel mindig naprakészen tartasz), ami azt az adatot tartalmazza, ami neked kell, és a neked nem kellő adatokat nem kell végignéznie (de egyszerű query esetén lehet, hogy a view nem lassú).
Esetleg készíthetsz olyan materialised view-t vagy segédtáblát, amiben a neked kellő adatok ki vannak emelve: emp_no, current_title, current_salary. Így a lekérdezésed egyszerű is lesz és várhatóan elég gyors is.
disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.
Az indexelésen már túl vagyunk, a dátum mezőkön van index; azt meg még csak beledrótoztam volna a PHP-ba, hogy ha az az egyetlen index hiányzik a
`salary`
-ról, akkor belerakom, de sajnos nem segített.Materialised view-et már kérdezték, sajnos ez MySQL - ahogy gelei kolléga fogalmazott - itt nincs ilyen.
Az egyes pontban lehet, hogy igazad van, de hunludvig javaslatával minden baromi gyors lett, csak a
`salary`
-re rendezés nem. (Ill. a`dept_name`
-ra sem, de azt tényleg el kell fogadni, mert egy kettős csatolás mögött van és amíg szűrni lehet rá azzal az egyszerű trükkel, hogy előtte egy pillanatnyi lekéréssel leszedem a`dept_no`
-t és azzal szűrök helyette, ez a sorrendezésnél nem működik sajnos...)Oldschool Computer - http://oscomp.hu
MySQLhez nem értek, de left join felesleges a where miatt, szerintem
én valami ilyesmivel is próbálkoznék (persze nagyban függ milyen execution plant ad hozzá)
És az a baj, hogy nem is értem, hogy ez a kód mit csinál, így azt sem tudom, hogy miféle syntax error van benne.
Oldschool Computer - http://oscomp.hu
row_number() MySQL 8-tol lett implementalva, nalad milyen verzio fut?
Support Slackware: https://paypal.me/volkerdi
Ez MySQL 5.5.valahánynak felel meg, ha jól tudom.
Oldschool Computer - http://oscomp.hu
https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.ht…
Ez a sorokat rendezi a táblában minden emp_no-n belül from_Date alapján csökkenő sorrendben. A row_number() ad egy sorszámot 1től az emp_no belül a a rendezésnek megfelelően. Tehát emp_no legnagyobb from_Date hez tartozó sorát adja vissza ha pos=1 re szűrök: (ha több azonos from_date van akkor is 1et!!)
durván(!) ezt csinálja:
Nem biztos, hogy jól értettem-e, de így gondoltad?
Mert ez hibát dob:
Az a baj, hogy ez már nagyon nem az én szintem...
Oldschool Computer - http://oscomp.hu
fejből írtam :) nyilván kell az aliasokat használni :) pos=1 már nem kell így.
Így már működött, de sajnos nagyon lassú volt, kb. 8 sec volt, mire lefutott.
Oldschool Computer - http://oscomp.hu
Mi az elvárás sebességre?
<1s. Ahogy hunludvig megoldásával megy.
Oldschool Computer - http://oscomp.hu
Az nem teljes (hiányzik még 3 tábla) és nálam az is 3 sec.
Magamnál kibővítettem amivel kellett. A szűrések dinamikusan kerülnek a lekérésbe, ahogy a sorrendezés is, de minden baromi gyorsan megy vele. (Kivéve a már említett fizetésre rendezést, de az sem mindig lassú, csak ha sok júzerrel kell dolgoznia.)
Oldschool Computer - http://oscomp.hu
Nem add vissza mindent.
lásd 10005 emp_no
Cserébe gyors! :P
Rossz a where záradék.
Ővé: 300024 rekord
Enyém: 331603 rekord
Eközben az employees tábla: 299512 :)
Na megyek aludni! :P
SELECT count(*) FROM `employees`; -> 300024
Gyanús ;)
És tényleg. Hát ezért vinnyog ez, amikor összefésülném a táblákat: tényleg duplikáció van a PRIMARY KEY alatt. Ezt hogy hozták össze...
Oldschool Computer - http://oscomp.hu
SELECT count(DISTINCT emp_no) FROM `employees`; -> 300024
Mármint hol van neked duplikáció?
Akkor én ezt most nem értem. Az
`employees`
táblában 299025 sor van a DB szerint. Ha lekérem a számosságot, akkor nekem is 300024. Ha megpróbálom összefésülni a főtáblát a három segédtáblával (ld. itt), akkor beszól, hogyError in query (1062): Duplicate entry '21076' for key 'PRIMARY'
, márpedig a frissen kreált - azaz üres - táblában a PRIMARY KEY az az`emp_no`
, tehát a bejövő`emp_no`
-k között ismétlés van. Vagy nem?Oldschool Computer - http://oscomp.hu
Próbáld ki ezt:
SELECT employees.*
FROM employees
LEFT JOIN titles ON titles.emp_no = employees.emp_no
AND titles.from_date = (SELECT MAX(from_date) FROM titles WHERE titles.emp_no = employees.emp_no)
AND titles.to_date = (SELECT MAX(to_date) FROM titles WHERE titles.emp_no = employees.emp_no)
LEFT JOIN salaries ON salaries.emp_no = employees.emp_no
AND salaries.from_date = (SELECT MAX(from_date) FROM salaries WHERE salaries.emp_no = employees.emp_no)
AND salaries.to_date = (SELECT MAX(to_date) FROM salaries WHERE salaries.emp_no = employees.emp_no)
LEFT JOIN dept_emp ON
dept_emp.emp_no = employees.emp_no
AND dept_emp.from_date = (SELECT MAX(from_date) FROM dept_emp WHERE dept_emp.emp_no = employees.emp_no)
AND dept_emp.to_date = (SELECT MAX(to_date) FROM dept_emp WHERE dept_emp.emp_no = employees.emp_no)
LEFT JOIN departments ON dept_emp.dept_no = departments.dept_no;
Ugyanaz a helyzet, mint előtte. Ha egy azonos
`emp_no`
-hoz több csatolt sor is tartozikakkor duplikálva jelennek meg a sorok.
Oldschool Computer - http://oscomp.hu
Nálam ez van lekérésnek:
És ez 240124 sort ad vissza. A
'9999-01-01'
-re szűrések miatt amire a csatolt táblában nincs infó, az kiesik. Ha kiszedem őketakkor 300053 sort ad. Valahol duplikációk vannak...
Az eredeti lekérés, amit írtam
az is 300053 sort ad vissza. Márványra printelt windowsmanuallal ütném, aki kitalálta ezt az elcseszett DB szerkezetet, semmi épeszűség nincs benne; teljesen alap lenne, hogy még ha jegyezem is a korábbi csatolt állapotokat, a jelenlegit akkor is tárolom a főtáblában. Igazán nem lehet mondani, hogy azzal sok helyet pazarolnánk, amikor a fizetések táblája nagyobb, mint a főtábla. Mégis csak az lesz, hogy csinálni kell egy összevont táblát ebből, de ahhoz még ki kell derítenem, hogy mi a francra reklamál, hogy duplikáció van.
Oldschool Computer - http://oscomp.hu
Előfordulhatnak duplikációk a from_date-n emp_no. belül?
pl. napon belül takarító-> CEO-> takarító (from_Date=to_date), ill. bármilyen hibás update a táblán a múltban? stb.
Igen, fentebb hunludvig meg is találta.
Oldschool Computer - http://oscomp.hu
Gyakorló DB, nem arra van, hogy pontjó legyen, hanem arra hogy megtanulj komplex lekérdezést írni.
Ezt én értem, csak már gyakorlás alatt is célszerű lenne az ésszerűséget is gyakoroltatni. Szerintem. Persze lehet, hogy pont ezért ilyen, hogy kínodban inkább denormalizáld az egészet. :P
Oldschool Computer - http://oscomp.hu
Nálam ez ott kezdődik, hogy minden tábla első mezője egy "id" (aminek esetemben mindig is id a neve) ami autoincrement.
Aki adatból csinál kulcsot az sikeres ember nem lehet.
Majdnem pont ezen vesztünk össze egy kollégával nemrég. Ő ragaszkodott hozzá, hogy márpedig csak adatokból kulcs az egyetlen helyes irány, míg én érveltem a fenti létjogosultsága mellett, pláne, hogy a már így összerakott 500 tábla mellé ne kezdjen el saját utat bejárni. Már nem kolléga.
Minden adatmódosítás egyben index módosítás. Zseniális ötlet. :) Egyetemen amúgy a kolléga verzióját kérik számon.
Volt phd-je :)
Mondjuk, ha az iskola az, hogy nincs adatmódosítás és törlés, kizárólag csak beszúrás van, akkor már kiegyenlített a kérdés.
Lehet mi vagyunk ahhoz kevesek, hogy felfogjuk az igazat.
Ez amúgy is igaz. Ha olyan oszlopot updatelsz, amire sűrűn kérdezel le, akkor amúgy is van rajta index, hogy a lekérdezés gyors legyen. És az ilyen oszlop módosításakor módosul az index is.
Általában a kompozit kulcsot adó adatot amúgy nem módosítod sűrűn - pont ezért lehet ő kompozit kulcs. Updatelni olyan adatot szokás, ami módosulhat úgy, hogy anélkül a sor identitását adó kulcs megváltozna.
Hiszen csak úgy nem birizgálunk ID-t a létrehozás után - akár kompozit kulcs, akár surrogate kulcs. Pont azért tud a kompozit kulcsban adatoszlop szerepelni mesterséges kulcs helyett, mert ez adja az adott sor identitását és nem igazán változik.
A surrogate key inkább azért szokás, mert akkor könnyű a kulcsot szerializálni, és máshol hivatkozhatóvá tenni.
Amúgy autoinrement mező helyett UUID sokkal jobb megoldás, több szempontból is.
Ez érdekelne.
disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.
Elosztott adatbázisoknál, pl. multi-master replication, egy bevett szokás. Jár valamennyi teljesítmény vesztéssel, meg a rendezhetőség veszik el, cserébe elég sok fejfájást meg tud spórolni, ha véletlen rossz helyre sync-kel az adatod (hogy ezzel de sokat szoptam már életemben...).
Az első pont a biztonság. Ha neked autoincrement azonosítóid vannak, akkor egy azonosító megszerzése után nagyon könnyen tudok következtetni más, valid azonosítókra és azokra lekérdezéseket futtatni stb. Ha kiadok több ilyen azonosítót valahova, akkor abból lehet következtetni sok mindenre. Akár még ipari kémkedésre is adhat információt az, hogy egy adott időszakban X volt az autoinrement mező értéke, másik időszakban meg Y.
Gondolj bele, mi lenne, ha a session azonosítók autoincrement mezők lennének valamilyen opaque azonosító helyett. Ha valaki megszerez egy élő session-azonosítót, akkor utána próbálkozás alapon a közeli azonosítókat végigpróbálva egy csomó érvényes session-be bele tudna nézni.
Ha UUID-et használsz, akkor hiába tud meg valaki egy érvényes azonosítót, nem tud következtetni arra, hogy mik a más érvényes azonosítók.
A második pont a megoszthatóság: egy UUID által azonosított adattáblát bármikor particionálhatsz több fizikai szerverre, az adattáblák a többi partícióval való kommunikáció nélkül is értelmesen frissíthetők.
Az UUID-ek ugyanis globális azonostók. Ha több, egymástól fizikailag elkülönülő szervezet (pl. egy multicég több üzeme sok országban - mondjuk a Tesco üzemek) azonosítani akarnak globálisan pl. a megrendeléseket, akkor a magyar, angol, lengyel, francia stb. adatbázisok sorai között sem lesz ID-ütközés, annak ellenére, hogy ezek az adatbázisok egymástól függetlenül frissülnek. Azaz egy azonosító globálisan csak egyszer fog szerepelni egy adattáblában, ahelyett, hogy ki kéne találni, hogy a 21324 ID az az angol, francia vagy magyar eladási adatbázisban van benne.
A harmadik pont a skálázhatóság: UUID által azonosított táblák esetén általában a beszúráskor a kliens határozza meg az új azonosítót, és nem a szerver. A kliensre van bízva, hogy generáljon egy érvényes UUID-et, ezáltal nem a szerver erőforrásait foglaljuk, amikor a sok-sok konkurrens tranzakciónál megpróbálja kitalálni, hogy melyik tranzakcióban beküldött adatsornak mi lesz az ID-ja. A kliensek meg tudják ezt anélkül tenni párhuzamosan, hogy ütköznének az UUID-ek.
Nyilván, előfordulhat ütközés - de ennek a valószínűsége kisebb, mint annak, hogy jön egy földönkívüli hadsereg és elpusztítja az adatbázist.
Erről volt már egy rendkívül tanulságos thread a hupon :D
Belinkelnéd? Nem tudom, melyikre gondolsz.
innentől lefelé
OMG, 7 éves thread. De nagyon jó :D
Jöttek és elpusztították? :-O
disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.
+1
Oldschool Computer - http://oscomp.hu
jahogyjaaaaaa.....
Elhagynám a legutolsó bejegyzés keresést és nézném adott dátumra. pl:
select e.*,s.salary,t.title
from employees as e
left join salaries as s
on e.emp_no = s.emp_no
and '2020-10-01' between s.from_date and s.to_date
left join titles as t
on e.emp_no = t.emp_no
and '2020-10-01' between t.from_date and t.to_date;
Ez sajnos ugyanúgy duplikált sorokat ad vissza, ha több azonos
`from_date`
van per`emp_no`
.Oldschool Computer - http://oscomp.hu
Így van de ez egy gyakorló db szóval .....
Telepítettem Mysqlt + az employees db-t .
Ha hozzá adtam csak ezt a két indexet.
ALTER TABLE `employees`.`salaries` ADD INDEX `s` (`salary` DESC) VISIBLE;
ALTER TABLE `employees`.`titles` ADD INDEX `t` (`title` DESC) VISIBLE;
Az eredeti query töredék idő alatt fut le :)
index nélkül 4 sec, indexel 0.5 sec.
Melyik eredeti query? Ez? Mert ez sajnos nekem lassú maradt.
Oldschool Computer - http://oscomp.hu
a topic indító :)
Ja, tényleg, az nekem is, köszi. :)
Mondjuk, ami most van, az a szerkezet megváltoztatása nélkül is gyors; még kitalálom, hogy mit csináljak, mert most már közeleg a deadline... :/
Oldschool Computer - http://oscomp.hu
-
Így sikerült összeállítani a denormalizált táblát:
Csak sajnos ez 25+ sec. Igaz, hogy csak egyszer kell lefuttatni.
Oldschool Computer - http://oscomp.hu
Az addig oké, hogy ez employee-nként egy sort fog adni, de az a LIMIT 1 valami eléggé ordas logikai bukfencre utal. Talán itt az ideje elmeditálni rajta, hogy mit is szeretnénk kinyerni és értelmezni a DB struktúrát.
Nincs kizárva. A
LIMIT 1
azért van benne, mert különben bereklamál, hogy több sort ad vissza és megáll. Próbáltam máshogy, de az meg duplikált sorokat adott ki.Oldschool Computer - http://oscomp.hu
Egyébként a
`dept_emp`
táblában van egy ordas nagy bug az indexekkel, nevezetesen, hogy be van lőve PRIMARY-nak az`emp_code`
és a`dept_no`
együtt, így aztán ezzel a táblaszerkezettel olyat nem lehet, hogy valakit áthelyeznek egyik osztályról egy másikra, majd vissza, ugyanis ahhoz be kéne szúrni az ID-jét és az osztály ID-jét, ami kombó már létezik és nem engedi... Drakulálok. A másik két táblához hasonlóan itt is a`from_date`
kellett volna, hogy legyen az`emp_code`
párja.Oldschool Computer - http://oscomp.hu
Van még generálva két nézet is.
És? Abba nem lehet adatot beszúrni. Egyébként a `
salaries
` is el van cseszve, mert ott meg hibádzik a PRIMARY kombóból a`salary`
, így egy nap csak egyszer változhat meg a fizetés.Oldschool Computer - http://oscomp.hu
Hogy ne csak beleokoskodjak:
Eredménye:
1751 rows in set (3.525 sec)
Ha viszont limit 0,20- al futtatom, akkor 0.276 mp alatt lefut.
Feladat szöveges megfogalmazása: válaszd ki azokat akiknek az utolsó titulusa staff, és az utolsó fizetése >= 120000.
Ez a query nem az utolsó fizetést és titulust hozza le :) (ld fizetés csökkenés illetve pozicó váltás Staffról)
Nekem
limit 0,20
-szal 1.5 sec volt, ami még mindig elfogadható, bár lassabb, mint ami most van. Viszont tényleg más eredményeket ad ki, mint amit kéne.Oldschool Computer - http://oscomp.hu
Csak kíváncsiságból, milyen gépen futtatod a DB-t? Nekem sima Win10 laptop, 8G ram, WSL alatt futtatva a mariadb-t adott ki iliyen eredményt. Azt hittem nálad gyorsabb lesz :)
A konfigom (lusta voltam leszűrni a releváns részeket, Ctrl+C/Ctr+V):
8 éves gép, de azért még 2020-ban is megállja a helyét. Úgy-ahogy... :P
Sz*rk: Egyébként szerintem neked a második lekérés, amikor a limitet is ráhúztad, az már a cache miatt gyorsult annyit, hiszen ugyanazt a lekérést kérted le még egyszer, csak ezúttal limittel.
Oldschool Computer - http://oscomp.hu