MySQL csak 25%-on dolgoztatja a CPU-t.

Fórumok

Sziasztok!

Van egy elég bonyolult sok subqueryt tartalmazó lekérdezésem.

SELECT
C.ID,
C.NEVROVID AS KOD,
C.NEV AS MEGNEVEZES,
C.KISZERELES_2_VALTOSZAM AS KARTONOS,
C.KISZERELES_1_VALTOSZAM AS DOBOZOS
FROM CIKKTORZS C,
(SELECT ACS.*
FROM AR_CIKK_OSSZERENDELO ACS,
(SELECT
ID_CIKK,
MAX(DATUM_TOL) DATUM_TOL
FROM AR_CIKK_OSSZERENDELO
GROUP BY ID_CIKK) ACF
WHERE ACS.ID_CIKK = ACF.ID_CIKK
AND ACS.DATUM_TOL = ACF.DATUM_TOL) AC,
(SELECT BAS.*
FROM BESZERZESI_ARAK BAS,
(SELECT
ID_CIKK,
MAX(DATUM) DATUM
FROM BESZERZESI_ARAK
GROUP BY ID_CIKK) BAF
WHERE BAS.ID_CIKK = BAF.ID_CIKK
AND BAS.DATUM = BAF.DATUM) BA
WHERE C.ID = AC.ID_CIKK
AND C.ID = BA.ID_CIKK
AND AC.ID_AR_TIPUS = 1
AND C.ID_CIKKCSOPORT = 1

A lekérdezés 4:20 percig fut de csak 25%-ot használ ki a CPU-ból.

Az egyes táblákban
CIKKTORZS : 44949
AR_CIKK_OSSZERENDELO: 45041
BESZERZESI_ARAK:46796
rekord található.

EXPLAIN:


1 PRIMARY ALL 44944
1 PRIMARY ALL 44959 Using where; Using join buffer
1 PRIMARY C eq_ref PRIMARY,FK_CIKKTORZS_10 PRIMARY 4 AC.ID_CIKK 1 Using where
4 DERIVED ALL 44944
4 DERIVED BAS eq_ref PRIMARY PRIMARY 7 BAF.ID_CIKK,BAF.DATUM 1
5 DERIVED BESZERZESI_ARAK range PRIMARY 4 47358 Using index for group-by
2 DERIVED ALL 44946
2 DERIVED ACS ref FK_AR_CIKK_OSSZERENDELO_01 FK_AR_CIKK_OSSZERENDELO_01 4 ACF.ID_CIKK 1 Using where
3 DERIVED AR_CIKK_OSSZERENDELO index FK_AR_CIKK_OSSZERENDELO_01 4 45453

Miért csak 25%-ot használ ki a CPU-ból a MySQL?

Hozzászólások

Milyen operációs rendszer? Mert ha Windows, akkor négy CPU mag (vagy kettő + HT) esetén 1 mag maximális kiterhelése esetén 25%-ot láthatsz a Task Manager-ben.

Szerintem 4 magos CPU-d van.
Egy query, egy mag.

Külső scriptekkel lehet párhuzamosítani.
---
"A megoldásra kell koncentrálni nem a problémára."

A sok magos rendszerek nem csak sql esetén a sok kérést tudják párhuzamosan kiszolgálni. Nehéz olyan algortmust írni, ami egymagában több magot használ, párhuzamosítható.
A mysql speed testek is arról szólnak, hogy 1000-10000 kérés/mp esetén tud-e még menni, ha a kapcsolódott kliensek száma 150-250. Itt egy kliensről van szó...

Az nem lehet, hogy a művelet közben sokat vár I/O-ra azért nincs a CPU jobban kihasználva?
--
Tertilla; Tisztelem a botladozó embert és nem rokonszenvezem a tökéletessel! Hagyd már abba!; DropBox

ez egy eleg elbaszott query igy elsore...

t

én sokáig követtem az szép kveriket, ahogy tanitották, de rájöttem, hogy valojában úgy a lassu. van amikor jó, de sokszor igazolodott be, hogy amire a suliba egyest adnak éles terhelt környezetben az fut szépen. tehát probálgatni kell.

------------------------
Jézus reset téged

Ezt ugye nem gondolod komolyan? :)
Természetesen tudnám, de nem akarom, az alábbi okok miatt:
- csak megsejthetem a mezőneveket, és kapcsolatokat
- a bevágott query-d nincs rendesen tördelve, olvashatatlan, és innen meg nem mondja senki hány szint mélyre mentél subselect-ekkel
- nem az én dolgom
- úgy nem tanulsz

Javaslom nézz utánna a JOIN-nak: http://lmgtfy.com/?q=mysql+join+example

(off: amíg aktívan SQL-eztem, ha a kolléga segítséget kért a query-jében, és ha olyan volt a külalakja mint a tiédnek el sem olvastam, visszadobtam, azzal, hogy "ha olvasható lesz megnézem".
Annak idején eluntam, hogy más helyett én tördeljek, csak azért hogy segíthessek neki. Ilyet többet nem csinálok. J /off)

---
"A megoldásra kell koncentrálni nem a problémára."

Csak hogy egy lépéssel (na jó, fél lépéssel) előbbre is juss:


SELECT
C.ID,
C.NEVROVID AS KOD,
C.NEV AS MEGNEVEZES,
C.KISZERELES_2_VALTOSZAM AS KARTONOS,
C.KISZERELES_1_VALTOSZAM AS DOBOZOS,
ACS.DATUM_TOL DATUM_TOL,
BAS.DATUM DATUM
FROM CIKKTORZS C,
LEFT JOIN AR_CIKK_OSSZERENDELO ACS ON ACS.ID_CIKK = C.ID
LEFT JOIN BESZERZESI_ARAK BAS ON BAS.ID_CIKK = C.ID
WHERE ACS.ID_AR_TIPUS = 1
AND C.ID_CIKKCSOPORT = 1

A jelenlegi ismereteimmel és az erre fordított 5 perccel, a megadott információkból ennyit tudtam összekalapálni.

Szerk: Ettől függetlenül petersonnak igaza van.

szerintem ennek az egésznek így semmi értelme
reméld hogy a táblákat nem ugyan az csinálta, mint aki a query-t

mivel mezőket csak a [cikktorzs] táblából jelenítesz meg, így volt két felesleges SELECT
mivel a dátumokat sem használod, így a MAX-olás is felesleges
"ACS.ID_AR_TIPUS = 1" sem ideális helyen volt

SELECT
C.ID,
C.NEVROVID AS KOD,
C.NEV AS MEGNEVEZES,
C.KISZERELES_2_VALTOSZAM AS KARTONOS,
C.KISZERELES_1_VALTOSZAM AS DOBOZOS
FROM CIKKTORZS C
INNER JOIN (
SELECT ID_CIKK,
FROM AR_CIKK_OSSZERENDELO
WHERE ACS.ID_AR_TIPUS = 1
GROUP BY ID_CIKK
) AC ON C.ID = AC.ID_CIKK
INNER JOIN (
SELECT ID_CIKK
FROM BESZERZESI_ARAK
GROUP BY ID_CIKK
) BA ON C.ID = BA.ID_CIKK
WHERE C.ID_CIKKCSOPORT = 1

A MAX-olás egyáltalán nem felesleges mert az AR_CIKK_OSSZERENDELO és a BESZERZESI_ARAK táblában egy cikkhez több rekord is tartozhat. Az árak változását tartalmazza .

Pl. az 1-es ID-jű cikkhez a AR_CIKK_OSSZERENDELO táblában két rekord található egy 100 Ft-os ár 2017.01.01 dátummal és egy 132 Ft-os ár 2017.01.25 dátummal ami az érvényességi idejét jelenti. Ma ugye 2017. 02. 03. van így nekem csak a 132 Ft-os ár kell.
Ugyan ez a szisztéma a BESZERZESI_ARAK táblánál is.

Tehát nekem kellet egy select ami vissza adja cikkek aktuális beszerzési és eladási árait. + kell bele egy cikkcsoport és egy ártípus szűrés.

Mea culpa a kötekedésért.
Tom megoldása adja magát ha feltételezzük hogy mit akart a költő. Magam is erre jutottam először.
Azonban ha nem minden cikk ID szerepel a másik két táblában akkor nem ugyan azt az eredményt adhatja mint az eredeti query. Abban az esetben csak Tom megoldás a jó, és az eredeti query hibás. Ezért is láttam meg a kihívást annak átírásában úgy hogy ugyan azt eredményt adjam vissza minden esetben.
Valamint a SELECT a dátumokat és árakat sem használta, így azokat elimináltam.

Hogy érdemben is hozzászóljak. Írtam az eredetidhez hasonló SELECT-et ugyan így 3 táblára. Mindegyik tábla: innodb, több mint 150 ezer sor, indexelve csak az ID-k voltak.
i5-2400, Ubuntu 16.04, mysql restart után visszaadott 125.004 sort 2,3 sec alatt. A visszaadott oszlopokra voltak mezőkonverziók if-ek stb.
Ez alapján nem a query-t gyanúsítanám.

iotop mit súgott?
MySQL beállításoknál próbálkozz ezzel ha nem értesz hozzá: https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltun…

Nem bantasbol, de mint jol lathatoan sem a linux sem a mysql alapveto mukodesevel nem vagy tisztaban igy javaslom keress egy hozzaertot aki tamogatja a munkadat. Ha meg hobbiprojekt akkor merulj egy a google bugyraiban.

Mysql nem szereti a subquery-t. meg ugy generalisan semmi sem. az oracle erolteti, de ok optimalizaljak is rendesen vegrehajtas elott, es amugy is az oracle elb*ttsagarol hosszasan lehetne ertekezni.

Ird at a query-t join-os megfejtesre, akkor explain-nel latni fogod, mi a gebasz. Ha szukseges, straight join-nal tudod javitani a mysql alap optimalizalasat, bonyi query-knek jol johet.

Vagy hasznalj mongodb-t.

MySQL is slow as a dog. MongoDB will run circles around MySQL because MongoDB is web scale.

"MongoDB does have some impressive benchmarks, but they do some interesting things to get those numbers. For example, when you write to MongoDB, you don't actually write anything. You stage your data to be written at a later time. If there's a problem writing your data, you're fucked. Does that sound like a good design to you?"

If that's what they need to do to get those kickass benchmarks, then it's a great design.

"..... If you were stupid enough to totally ignore durability just to get benchmarks, I suggest you pipe your data to /dev/null. It will be very fast."

Legalább megnézted? Felfogtad miről van szó? Miért cserélje le a meglevő rendszerét? fanboy..

néhány dologra jó a monogo, de itt épp szóba se jött.
Minden webshopod alatt mongo van "a microservice-ek vilagaban egyertelmuen mongo a nyero" ? -.-

Hát... PostgreSQL-ben elkezdtek dolgozni a paralelizáció támogatásán, nem tudom mennyit hoz. 9.6-ban bejött már egy kezdeti támogatás.

Viszont tapasztalataim alapján a tábla particionálás is rengeteget tud gyorsítani nagy tábla esetén.

https://www.postgresql.org/docs/9.6/static/parallel-query.html

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Gondolom 100%-on teker egy mag 4 percig. Amin a queryt nézve sztem nem is kell csodálkozni.

Sztem sorrendben ezekkel kéne próbálkozni, csökkenő nyereségi sorrend:

1. a séma újra gondolása, a tipikus querykhez igazítás.
2. indexek kreálása, ahova kell.
3. táblák alatt DB engine váltás, (pl. InnoDB helyett TokuDB)

(és vagy 0. vagy 4. a másik adatbázisra váltás, csak ennek a költsége elég nagy. Ezt csak nagy vész esetén javasolnám.)