Mysql lekérdezések optimalizálása
2010-06-16T12:35:11+02:00
2010-06-29T18:58:07+02:00
2022-07-19T04:44:07+02:00
  • Egy teljes query és egy explain sokat segítene az optimalizálásban.

    Az biztos, hogy az inner join elegendő (hiszen a bal tábla egy mezőjére van nem NULL feltétel, így eleve kiszűröd a left join-ból eredő null-os rekordokat)

    Érdekes lehet még, hogy valóban milyen indexeket használ és a groub by illetve order by milyen mezőkre érvényes (ez sajnos néha megzavarja szerencsétlen mysql-t és elfelejt rendes indexet használni - tapasztalat)

    Nem javasolt, de ha nincs más megoldás, használhatod ezt is: MySQL :: MySQL 5.5 Reference Manual :: 13.2.9.3 Index Hint Syntax
    Mutasd a teljes hozzászólást!
  • Duplázva mentettem el ugyanazon oszlopra vonatkozó indexet, ezért lett ilyen lassú a lekérdezésem. De most is 1,8 mp környékén van..
    Mutasd a teljes hozzászólást!
  • Szia.

    Kizárt, hogy subquery-t használjak itt. Le is kapcsolnák a servert 1 perc alatt.
    Mutasd a teljes hozzászólást!
  • Vagyis teljesen egyezo tipusu index kell mindket tabla osszekapcsolt mezojere. Vagyis ha az egyik int(10) a masik int(9) az mar nem jo, mindkettonek teljesen meg kell egyeznie.

    Ez természetesen nem így van.

    Ez sajnos igy van.


    És szted mi a különbség mysql-ben a kettő között? Sztem semmi. Csak megjelenítésre (paddingra) vonatkozik a (10).
    Mutasd a teljes hozzászólást!
  • A left join kis méretnél lassabb, mint az in-es szerkezet, ahogy nő viszont a rekordszám, úgy lesz egyre jobb, mert egyre nagyobb lesz a költsége az in-es szerkezetben lévő származtatott tábla előállításának.
    Mutasd a teljes hozzászólást!
  • Ez sajnos igy van.


    Nem így van, mert az int(9) és az int(10) az ugyanaz az adattípus, a zárójelben lévő hossz a megjelenítést szabályozza, nincs semmilyen típus konverzió (lásd zerofill tulajdonság). Típus konverzió mondjuk egy varchar(10) és int(10) típusú mező között van.

    Amire te gondolsz az az lehet, hogy amikor subquery vagy származtatott tábla miatt a mysql ideiglenes táblát hoz létre a join leképezéséhez, és valamelyik ilyen korlátozott mezőben hosszabb adat van, mint amit a megjelenítésnél beállítottál, akkor az problémát okozhat. De ez esetben sem az a probléma, hogy az egyik index int(9) és a másik int(10), hanem az, hogy pl. az int(9)-es mezőben egy 10 számjegyes szám található.

    Csak elegendo belegondolni, hogy verziokezelo tablazatrol beszelunk. Ennek eredmenyekepp egyszerre tobb verziot kell a tablabol a memoriaban tarolni (ha megfeleloen van beallitva).


    Természetesen nem táblákból tárol több verziót a memóriában, hanem lapokból. De a myisam-nál is megcsinálja, hogy a gyakrant használt lapokat (vagy legalábbis az utoljára használtakat ) és index lapokat benntartja a memóriában - ha beállítod ezt neki. És ha beállítod, akkor máris nem eszik több memóriát az innodb, mint a myisam. Ez tapasztalat a részemről.

    azonban a tranzakciokezeles opcionalis az innodb-ben es nem kotelezo eleme.


    Hát, én csak az autocommit-ról hallottam eddig, de annál bizony ugyanúgy van tranzakció kezelés. Én nem tudok olyan paraméterről az innodb-ben, amivel a tranzakciókezelés letiltható lenne. Meg minek is tiltanák le? Ha nincs tranzakció kezelés, akkor tényleg használhatnak már myisam-ot. És pont ezért az adat módosító utasítások mindig legalább 5-8%-kal lassabak innodb-nél, mint myisam-nál.

    De ha meg tudod nekem mutatni, hogyan tiltod le innodb alatt a tranzakció kezelést, akkor elismerem, hogy a beszúrás innodb alatt lehet gyorsabb, mint myisam alatt.

    A select lekerdezesek sem minden esetben gyorsabbak a myisamnal. Termeszetesen az elsodleges kulcs alapu lekerdezesek gyorsabbak (az innodb indexelesi modja miatt), azonban az ettol elteroek lassabbak


    Ez sem így van. A myisam blob mezőkben történő keresés esetén veri nagyon az innodb-t, illetve nagy számú (>256) szál esetén bizonyos lekérdezés típusoknál behozza vagy lehagyja az innodb-t. Ami nagy előgy a myisam-nál az a fulltext index, illetve a sokkal gyorsabb full table scan (ha arra van valamiért szükség, mondjuk egy left join-nál).

    Méréseket itt találsz.
    Mutasd a teljes hozzászólást!
  • products_modell_conn.product_id legyen indexelve, illetve lehet még az sql-t átírni úgy, hogy:

    select p.id, p.name from products where p.id in ( select product_id from products_modell_conn WHERE modell_id = xx )
    Mutasd a teljes hozzászólást!
  • Vagyis teljesen egyezo tipusu index kell mindket tabla osszekapcsolt mezojere. Vagyis ha az egyik int(10) a masik int(9) az mar nem jo, mindkettonek teljesen meg kell egyeznie.

    Ez természetesen nem így van.


    Ez sajnos igy van. Sajnos mar nem tudom megmondani, hogy a mysql manualban valamelyik optimalizacioval foglalkozo konyvben vagy egy kulon konferencia videoban lattam, de csak elegendo belegondolni abba, hogy konvertalnia kell egyik tipusrol a masikra a mysql-nek, hogy az osszehasonlitast el tudja vegezni. Ha egyszer ujra megtalalom, belinkelem neked.


    Igazából plusz memóriát vagy proci kapacitást nem igényel a myisam-hoz képest.


    Sajnos a tapasztalataim nem ezt mutatjak es a nalam tapasztaltabbak forumbejegyzesei, blogjai sem. Csak elegendo belegondolni, hogy verziokezelo tablazatrol beszelunk. Ennek eredmenyekepp egyszerre tobb verziot kell a tablabol a memoriaban tarolni (ha megfeleloen van beallitva). A processzor pedig kell a kulonbozo irasi bufferek es az eles tablak mergelesehez.
    Ezen kivul meg tobblet tarhelyet is igenyel eleg szep mennyisegben.


    Az innodb az adat módosító utasítások (insert/update/delete) esetén teljesít lassabban a myisam-nál a tranzakciókezelés miatt, de a select-eknél (különösen az intervallum keresésnél) jóval gyorsabb tud lenni a myisam-nál.


    Ez igy nem teljesen igaz. Az igaz, hogy elteroen kezeli a kulonbozo modosito utasitasokat, azonban a tranzakciokezeles opcionalis az innodb-ben es nem kotelezo eleme. A lassulast pedig az adatkezelesi mod megfelelo beallitasaival el lehet tuntetni. A select lekerdezesek sem minden esetben gyorsabbak a myisamnal. Termeszetesen az elsodleges kulcs alapu lekerdezesek gyorsabbak (az innodb indexelesi modja miatt), azonban az ettol elteroek lassabbak.
    Mutasd a teljes hozzászólást!
  • Vagyis teljesen egyezo tipusu index kell mindket tabla osszekapcsolt mezojere. Vagyis ha az egyik int(10) a masik int(9) az mar nem jo, mindkettonek teljesen meg kell egyeznie.


    Ez természetesen nem így van.

    de az InnoDB nagyobb szerverigennyel bir a MyISAM-hoz kepest (meg rengeteg elonnyel)


    Ez így teljesen nem igaz. Az innodb jobban skálázódik, azaz ugyanolyan szerver és beállítások mellett nagyobb teljesítményre képes, mint a myisam nagy terhelés mellett. Az innodb az adat módosító utasítások (insert/update/delete) esetén teljesít lassabban a myisam-nál a tranzakciókezelés miatt, de a select-eknél (különösen az intervallum keresésnél) jóval gyorsabb tud lenni a myisam-nál. Igazából plusz memóriát vagy proci kapacitást nem igényel a myisam-hoz képest.

    Az indexek és a táblamotor az egy dolog, de a szerver paraméterezésével is jelentősen javítani lehet a lekérdezések teljesítményén, de ezt mindenkinek a saját környezetében kell kitapasztalnia, általános jótanács nem létezik! A mysql online kézikönyvében egy teljes fejezet foglalkozik a lekérdezések optimalizálásának különböző szempontjaival itt, ennek ismertetése azért meghaladja egy fórum kereteit. Jó olvasgatást hozzá!

    Azért annyit megjegyeznék, hogy egy left join igen kemény dolog tud lenni, ahogy nő a rekordok száma a join-ban résztvevő táblákban! Biztosan kell itt a left join, különösen a where feltétel elnézve?
    Mutasd a teljes hozzászólást!
  • Megfelelo indexeles a kapcsolo mezokon keresztul.

    Vagyis teljesen egyezo tipusu index kell mindket tabla osszekapcsolt mezojere. Vagyis ha az egyik int(10) a masik int(9) az mar nem jo, mindkettonek teljesen meg kell egyeznie. Ertelemszeruen az egyikben valoszinuleg elsodleges kulcskent fog szerepelni, a masikban pedig indexkent.

    Ha nem tortenik iras, akkor parhuzamosan ki kellene szolgalnia egyszerre tobb lekerdezest is. Ha viszont tortenik iras is, akkor elkepzelheto a MyISAM szerkezet eseten a lock-olas. Ebben az esetben ha atallitod InnoDB-re, akkor valamennyit segiteni fog rajta (legalabbis a lock-on), de az InnoDB nagyobb szerverigennyel bir a MyISAM-hoz kepest (meg rengeteg elonnyel)
    Mutasd a teljes hozzászólást!
  • Azert en egy EXPLAIN-el megneznem, hogy minden lekerdezes hasznalja-e az indexeket, mivel nem hiszem, hogy indexelt olvasásnál ilyen minimális mennyiségű adatnál ilyen lassulás lenne. Talán akkor, ha nincs elég memória kiadva a myslnek és cserélni kell a táblákat folyamatosan a memóriában.
    Mutasd a teljes hozzászólást!
  • Sziasztok.

    Webshop fejlesztése közben a kapcsoló táblákkal merült fel egy optimalizálási kérdés. Néhány adat:

    Server: 4 magos intel processzor
    Adatbázis: mysql 5
    PHP: 5
    Termékek száma: 8ezer
    Modellek száma: 2ezer
    Termék-modell kapcsolatok száma: 55ezer
    Primary indexek: products.id, modells.id, (products_modell_conn.modell_id, products_modell_conn.product_id)


    Minden terméknek lehet több modellhez hozzárendelve:
    select p.id, p.name from products
    left join products_modell_conn m p.id=m.product_id
    where m.modell_id=xx

    Ilyen és ehez hasonló lekérdezések keserítik meg a server mindennapi életét. Ilyenkor 20-60 másodpercre elkezd gondolkodni, és addig más lekérdezés sorban áll. Kérdésem az lenne, hogy hogyan lehet optimalizálni.

    Minden lehetséges megoldás érdekel. Akár ha van más adatbázis motor, amely egy ilyen lekérdezést nagyságrendekkel (2mp alatt) tud végrehajtani, akkor az is szóba jöhet.

    Megj: a lekérdezést nem tudom szétválasztani, mert egy csomó order by, inner join-t tartalmaz. Viszont ezeket most nem másolom be, mert nem azok határozzák meg a lekérdezés gyorsaságát, hanem már ezen a szinten nagyon lassú.
    Mutasd a teljes hozzászólást!
abcd