MySQL lassú indexek
Sziasztok!
Egy elég érdekes problémába ütköztem, amit nem igazán tudok hova tenni - valószínű az indexekkel kapcsolatban vannak tudásbeli hiányosságaim. Eleddig azt hittem, hogy a mysql (myisam tábla) indexelt mezői a create, update és delete query-k esetén lassítanak, a select-eknél pedig gyorsítanak. Nálam egy esetben azonban az ellenkezője történt.
Adottak egy webáruház dinamikus adattagjaihoz (EAV) tartozó táblák (termékek tábla, attribútumok tábla, termékek-attribútumok kapcsolótábla). Ha az egyes termékeket azok sajátos attribútumai alapján szeretném szűrni egyetlen lekérdezésben, akkor az összes (a szűrésben részt vevő) tulajdonságot join-al hozzákötöm a termékek lekérdezéséhez. Ezzel nincs is semmi gond (attól eltekintve, hogy gigantikus query-ket lehet elérni már 10-20 ilyen szűrési feltétel esetén is), azonban a lekérdezés néha borzasztóan lelassult (1-10mp-es lekérdezések is születtek, amik vállalhatatlanok). Az egyéni attribútumokat tartalmazó táblában (idegen kulcs híján) az összes termék azonosítót indexeltem, gondoltam így gyorsabban találja meg a join-nál az egyes sorokat az adatbázis - azonban - mint az később kiderült - ezek az indexek okozták a lassú lekérdezéseket. Az indexek megszüntetésével a korábbi több mp-es query-k 0.01sec alá gyorsultak.
Ezt el tudná nekem valaki magyarázni, hogyan is történhetett? Milyen mezőket érdemes indexként használni?
Az teszt-adatbázisban jelenleg kevés adat található.
Köszönettel,
Drawain
■ Egy elég érdekes problémába ütköztem, amit nem igazán tudok hova tenni - valószínű az indexekkel kapcsolatban vannak tudásbeli hiányosságaim. Eleddig azt hittem, hogy a mysql (myisam tábla) indexelt mezői a create, update és delete query-k esetén lassítanak, a select-eknél pedig gyorsítanak. Nálam egy esetben azonban az ellenkezője történt.
Adottak egy webáruház dinamikus adattagjaihoz (EAV) tartozó táblák (termékek tábla, attribútumok tábla, termékek-attribútumok kapcsolótábla). Ha az egyes termékeket azok sajátos attribútumai alapján szeretném szűrni egyetlen lekérdezésben, akkor az összes (a szűrésben részt vevő) tulajdonságot join-al hozzákötöm a termékek lekérdezéséhez. Ezzel nincs is semmi gond (attól eltekintve, hogy gigantikus query-ket lehet elérni már 10-20 ilyen szűrési feltétel esetén is), azonban a lekérdezés néha borzasztóan lelassult (1-10mp-es lekérdezések is születtek, amik vállalhatatlanok). Az egyéni attribútumokat tartalmazó táblában (idegen kulcs híján) az összes termék azonosítót indexeltem, gondoltam így gyorsabban találja meg a join-nál az egyes sorokat az adatbázis - azonban - mint az később kiderült - ezek az indexek okozták a lassú lekérdezéseket. Az indexek megszüntetésével a korábbi több mp-es query-k 0.01sec alá gyorsultak.
Ezt el tudná nekem valaki magyarázni, hogyan is történhetett? Milyen mezőket érdemes indexként használni?
Az teszt-adatbázisban jelenleg kevés adat található.
Köszönettel,
Drawain
Nálunk is voltak gondok a
- érdemes ideiglenesen naplózni egy oldallekérés összes lekérdezését és azok futási idejét
- a MySQL EXPLAIN megmondja, hogy miként használja az adatbázismotor az indexeket, itt van egy nagyon jó leírás
- csak arra tegyél indexet, amire szükséges
Gábor! A "csak arra tegyél
A "csak arra tegyél indexet, amire szükséges" csak azért fontos, hogy ne lassítsa az update műveleteket és ne foglaljon felesleges helyet, ilyesmi...
Lekérdezést egy felesleges index _elméletileg_ nem lassíthat, mert az optimizernek kutya kötelessége lenne észrevenni, ha zavarja a lekérdezést. Viszont fogalmam sincs, nincs-e olyasmi a MySQL-ben, mint az Oracle statisztikái, amik a cost based optimalizáláshoz szükségesek. Ha van ilyen és az el van kefélve, az persze okozhat olyan jelenséget, amit a kérdező említett.
Egyébként nekem leginkább valami bugnak tűnik (persze igencsak hiányosak a MySQL ismereteim :( )
Igen, az írási műveletek
Viszont ebben az esetben úgy
(pl. - megintcsak Oracle tapasztalat, mysql-ben szerintem nincs ilyen - ha bekapcsolok valami spec. audit funkciókat, azok igencsak lelassíthatják a lekérdezéseket is.)
A where-ben, az order by-ban