Help! Egyszerüsíteni akartam egy php-vel összerakott MySQL lekérdezést. A MySQL 5.1 doksi szerint az INSERT-nél lehet használni azt a szerkezetet, amit az UPDATE-nél, tehát ez elvileg elfogadott:
INSERT database.table SET ( row1='data1', row2='data2', rowN='dataN' );
...de az eredmény:
You have an error in your SQL syntax; [...] near '( row1 = 'data1', row2 = 'data2', rowN = 'dataN' at line 1
...akkor pedig minden OK. A mezőneveket nem szoktam idézőjelbe tenni, a második példából nem is hiányzik a MySQL-nek. Az INTO megadása a doksi szerint opcionális. Mi a hiba az első módban?
Nézd meg a webszerver logot, elképzelhető hogy az oldal bekerült egy spam rendszerbe és ők generálják a forgalmat.
Vagy DOS támadás.
Meglepő hogy kis oldalak is milyen nagy forgalmat tudnak generálni hasonló esetekben.
Sajnos hosszú távon hatékony védekezést nem tudok, első lépésben lehet próbálkozni ip címek, domainek és országok (pl. .ua) tiltásával (pl. htaccess fájlban).
lehet, hogy egyre nagyobb eredmeny halmazt kernel el tole? tipikus: van 1 log tabla, amibe mennek az insertek, es van 1 alkalmazas, ami select * from logtabla;-t nyomat. Nyilvan, egyre novekedni fog az adatmennyiseg amit visszaad. "Feltoltest general" ennek ugye semmi ertelme, mivel a mysql nem general semmifele kommunikaciot (hacsak nincs replikacio)
Mivel, ha ilyet akarsz, az nem fulltext kereses :)
A fulltext kereses lenyege, hogy szavakra keresel. Okosabb fulltext keresok, amelyekhez tarsithato szotar is, tudhatnak többes számot, ragozásokat, stb, is kezelni. Lásd: word vs. words ...
Illetve a peldadban szereplo mar csak azert sem mukodne, mert alapbol talan 4 karakter a minimalis hossz amire keresni lehet :)
Köszönöm, ezt ismerem, ezt váltja a full text. Mostanra elég sokat olvastam róla és úgy tűnik, hogy MATCH xyz AGAINS rendszerben nem lehet %szó és %szó% típusú keresést csinálni. Párhuzamosan kell használni a LIKE-kal, vagy valami beépülőt (pl. Sphinx) kell telepíteni.
Full text search kérdés jöhet? Az egész szavas ('szó') és szóeleji töredékes keresés ('szó*') megy, de hogy lehet szóközi/szóvégi töredékre keresni? A '*szó', '*szó*' és a sima keresés %szó (vagy %szó%) technikája nem működik.
Egy teljesen tiszta gépre (amin még nem volt soha mysql) telepítettem a mysql szervert.
Telepítés rendben lement.
Elindul a mysql szervert konfiguráló program.
Megadok minden paramétert, majd pedig elkezdi végrehajtani a műveleteket.
Megcsinálja rendben a "Prepare configuration" majd a "Write configuration file", majd pedig a "Start service" dolgokat, utána következne a "Apply Security Settings", azonban itt hibával leáll.
Hiba üzenet a következő:
A gépen ugyan volt tűzfal program, de sem akkor ha az fut, sem akkor ha az nem fut, sem akkor ha engedélyezem vele a 3306 portot, akkor sem megy.
Előtte a gépen soha nem volt MYSQL telepítve, teljesen tiszta rendszer.
(ne is képezld el, hogy mi van mikor belerohad a felénél.. borzalmas.. álmatlan éjszakáid lennének :D )
Innodb-re azért nem álltam még át, mert nagyon régi a történet, másrészt vhogy úgy rémlett, hogy valamivel lassabb, és ilyen webshop-os történeteknél inkább myisam.. de lehet, hogy félreolvastam.. régen volt.
A trx kezelés igen jól jönne néha, már gondoltam rá, mivel egyre bonyolultabb az eset, már triggereket is használok, és nemsok kell, hogy pár dolgot átrakjak tárolteljárásba.
illetve meg1, ha az oldalrol jovo mysql keresek csak olvasnak a tablak-bol, azokbol amiket te amugy updatelsz a feldolgozobol, akkor az is 1 jo megoldas, hogy a feldolgozo csinal 1 masolatot a tablakrol amikor elindul, azokon dolgozik, majd a vegen rename-vel atcsereli a tablakat, es dobja a korabbi eles tablakat.
az utolso mondatod alapjan, velheto, hogy myisam tablaid vannak? Elso korben lehet erdemes volna innodb-re atalakitanod, mert myisam-nal, ha fut a feldolgozod es folyamatosan update akkor az az egesz tablat lock-olja, es varhatnak miatta az oldalrol jovok connection-ok amig hozzafernek az adott tabla(k)-hoz. Es ugye emiatt biztos, hogy tranzakciokat sem hasznalsz.
Innodb-vel viszont egyreszet az updatek nem full tablat, csak row lock-ot csinalnak (felteve, hogy nem full table update van), illetve ami meg fontosabb, hogy tudsz tranzakciokkal dolgozni. Azt nem javasolnam, hogy az egesz fel ora alatt futo folyamat-ban 1 tranzakciot hasznalj, hanem logikai egysegenkent. Ez egyreszt neked is jobb, mert ha valami miatt megszakad, akkor tudsz rollback-elni stb stb. Most el sem tudom kepzelni, hogy nezhet ki nalad, ha valami gond van es a feldolgozo a felenel elszal :)
Egy érdekes problémával küszködök, gondoltam feldobom a kérdést, hátha valakinek van ötlete rá.
Shop-okat fejlesztek, üzemeltetek (részben) és sok helyen megoldottam, hogy a belső ügyviteli rendszer az authentikus forrás, oda vételeznek be, ott számláznak, és a változásokat egy saját cuccom felupdateli a shop rendszerbe (raktár, ár, akció, új termék, megszünt termék).
Ez oly módon teszi, mivel a legtöbb ü.r. foxpros- dbf-es.. kigenerálok sok csv-t azt ftp-vel fel a szerverre, ott cron-ból fut egy cucc, ami berakja egy temp táblába (összeállítva a sok csv-ből azokat az adatokat ami kell), majd a temp táblából egy selecttel kiveszem az adatokat, és soronként nézem, hogy mi a tenedő. pl. ha olcsóbb árral jön, be kell akciózni, ha drágább, akkor levenni akcióból, meg raktár darabszám szerint aktivál, deaktivál..stb..stb..stb
Azért írom le ilyen részletesen, hogy lehessen látni mi zajlik le, tehát szerver oldalon cron-ból fut egy php-ban írt dolog, ami előszőr csinál kb 13.000 sor insert-et minden alkalommal, majd select, és update hegyek az éles táblákon.
A jelnség az, hogy mikor ez fut, és közben júzerek kattintgatnak az oldalon, akkor mostmár mindennapos, hogy mysql hibaüzenet, hogy elértem a max user connection számot (ami ennél a szolgáltatónál 25 és ő szerintük ez mindenkinek elégnek kell lennie).
Van mikor emiatt az update-em sem fut le, vagy megdöglik, vagy csak a júzerek kapnak hibaüzenetet.
Az én update-em, 1db connection-be csinál végig mindent, közben nem bontok le, és nem hívok meg semmi külső dolgot ami újra kezdeményezne további connectiont.
Mi lehet a gond? csak annyi, hogy a futási ideje ennek kb 30 perc, és ettől hasal el? (indexek, táblák 1000x átnézve, sajnos a sok insert és update tart ilyen sokáig)
Másik talán ehhez kapcsolódó dolog, hogy azt is megfigyeltem, hogy ha csinálok akár csak EGY db update-et az adatbázisban a következő select vagy 10mp-ig fut mire eredményt ad, majd utána már milisecundumok csak megint.
Nem ugyanazt írtam, mert azt a szintakszist nem értem, és szeretném megérteni, hogy legközelebb ne kelljen megkérdeznem. (még nem tudom mi az a 'belső SELECT')
Szóval, egyszerűsítem egy kicsit:
van egy table nevű táblám amiben egyetlen mező van, egy számérték, legyen a neve 'num'.
1. Ha szeretném megtudni táblázatbeli számok összegét, akkor:
SELECT sum(num) FROM table
2. Ha szeretném látni a 10 legnagyobb számot, akkor:
SELECT num FROM table ORDER BY num LIMIT 0, 10
Hová kell a 'belső SELECT', ha szeretném a 10 legnagyobb szám összegét tudni??
Így:
SELECT sum(num) FROM (SELECT num FROM table ORDER BY num LIMIT 0,10)
A zárójel kell oda vagy csak a jobb olvashatóság miatt írtátok?
Nem ugyanazt írtam, mert azt a szintakszist nem értem, és szeretném megérteni, hogy legközelebb ne kelljen megkérdeznem. (még nem tudom mi az a 'belső SELECT')
Szóval, egyszerűsítem egy kicsit:
van egy table nevű táblám amiben egyetlen mező van, egy számérték, legyen a neve 'num'.
1. Ha szeretném megtudni táblázatbeli számok összegét, akkor:
SELECT sum(num) FROM table
2. Ha szeretném látni a 10 legnagyobb számot, akkor:
SELECT num FROM table ORDER BY num
Hová kell a 'belső SELECT', ha szeretném a 10 legnagyobb szám összegét tudni??
Így:
SELECT sum(num) FROM (SELECT num FROM table ORDER BY num)
A zárójel kell oda vagy csak a jobb olvashatóság miatt írtátok?
Nem hibaüzenet volt, hanem az amit szavakban leírtam:
Nem az összegzést korlátozta a 10 legnagyobb értékre, hanem az outputot (számomra ez megjelenítés), azaz valamennyit összeadta és az első 10 azonosítóra kiírta nekem, holott én pont fordítva szerteném: csak a 10 legnagyobbat adja összes egy-egy azonosítóra és mindet mutassa meg (legyen nekem output).
Nem úgy van, hogy a LIMIT a megfelelő rekordok megjelenítését korlátozza?
Nekem nem a megjelenítésre, hanem az összegzésre kellene a korlát, azaz nem a teljes összegzés első tíz elemét akarom látni, hanem azonosítónként az első tíz (nagyság szerint rendezve ráadásul) összegét, de korlátozás nélkül az összes azonosítóra megjelenítve.
Egy táblázat soraiban levő számokat szeretném azonosítónként összegezni
id|num
1 | 2
1 | 4
1 | 7
...
3 |52
3 | 65
3 | 77
...
ezt ugyebár
SELECT sum(num) GROUP BY id
segítségével megkapom, de ez az összes azonos id-hez tartozó num-ot összegzi, nekem pedig azonosítónként csak a num-ra rendezett 10 legnagyobb érték összegére lenne szükségem. Hová forduljak? RTFM is elég...