MYSQL indexelés
Sziasztok!
Van egy MySQL táblám, melyben jelenleg kb. 3000000 sor van. Naponta kb. 15000-20000 sorral bővűl. A lekérdezést amikor megírtam 10000 sorra teszteltem, és gyors volt. Azután feltöltöttem az adatbázist és iszonyú lassú lett a lekérdezés. Hogyan lehetne gyorsítani?
tábla:lekérdezés:
■ Van egy MySQL táblám, melyben jelenleg kb. 3000000 sor van. Naponta kb. 15000-20000 sorral bővűl. A lekérdezést amikor megírtam 10000 sorra teszteltem, és gyors volt. Azután feltöltöttem az adatbázist és iszonyú lassú lett a lekérdezés. Hogyan lehetne gyorsítani?
tábla:
CREATE DATABASE kot;
USE fullkot;
CREATE TABLE kot (
instr VARCHAR(9),
vevo VARCHAR(10),
elado VARCHAR(10),
quant MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
price DECIMAL(8,2) UNSIGNED NOT NULL DEFAULT 0,
datum DATETIME NOT NULL DEFAULT 0
);
select instr, vevo, elado, sum(quant),
sum(quant*price)/sum(quant), sum(quant*price)
from fullkot
where vevo<>elado and datum >= \"$kezdatum\" and
datum <= \"$vegdatum\"
group by instr, elado
order by instr, elado;
MYSQL indexelés
A rengeteg SUM parancs, valamint a GROUP BY is lassíthatja. Néha megfontolandó, vagy legalábbis kipróbálásra érdemes, hogy nem gyorsabb-e az összeadásokat php-ból megoldani. Tehát lekérdezel valamit, (egyszerűbb sql-lel) és az összegeket a cikluson belül számolod ki. Én már lepődtem meg ilyesmin... :)
Gyulus
MySQL Optimization
néhány javaslat
A where záradékban sorban a nagyobb szelekciót adó feltétel legyen, az a feltétel legyen előrébb amivel nagyobb rekordszámot tudsz kizárni. Szerintem a vevo<>elado nem ilyen.
A vevo és az eladó mezők miért varchar típusúak? Nem idegen kulcsok? Az int összehasonlítások léptékekkel gyorsabbak, mint szövegek összevetése.
Ha ilyen sok adatod van, a fentiek miatt, érdemes a dátumot is int-ként, unix időbélyegként tárolni és between műveletet használni.
Nem baj, ha magyar elnevezést használsz. Sőt! Szerintem fontosabb helyeken, pl. tábla és mezőneveknél érdemes is magyar elnevezéseket használni, de ne keverd az angol és a magyar neveket. Egyébként mi az az instr mező?
Az adatok gyorsabb leválogatása végett, a tábla végén legyenek a változó szélességű mezők. Ha jól emlékszem group by után felesleges rendezni, ha ugyanaz a sorrend kell, az adatok már rendezve vannak.
De a legfontosabb az indexek használata és a varchar helyett int típusú mezők lehetőleg a dátum mezőnél is.
where-ben sorrend
Nem vagyok mysql szaki, de ezzel vitatkoznék. Amire te gondolsz az inkább pl a group by-having párosnál van. Az írásod szerint egy 100000-es sorú táblában végigmenne mind a 100000 soron (tegyük fel nincs index) - mert ugye valahogy el kell dönteni hogy mely sorok feletek meg -, és amik megfeleltek az első feltételnek, azokból csinálna egy kis halmazt, és utána úgymond ezeket a lépéseket rekurzívan végezné amíg újabb feltételek vannak???? Ezel kapásból több vizsgálat lenne mint ahány sor van! (Már az első feltételnél átnéztük az összes sort ahhoz, hogy ki tudjuk válogatni ami megfelelt)
Ez a where sorrend annyira meglepett, hogy gyorsan ki is próbáltam. De az eredmények engem igazolnak. Azaz mindegy a where-ben a sorrend, ugyanis szerintem soronként értékeli ki az adatokat az egész where feltételre nézve.
"Az adatok gyorsabb leválogatása végett, a tábla végén legyenek a változó szélességű mezők."
Ez miért lenne fontos?
Válasz
Hát nem ebben az értelemben gyorsabb. :) A where záradék utáni rész egy logikai kifejezés, aminek kiértékelésekor rövidzár kiértékelést történik. Azaz több feltétel esetén előfordulhat, hogy már az első feltételből kiderül, hogy az egész kifejezés igaz vagy hamis. Ekkor a többi ellenőrzést nem kell elvégezni.
Ez miért lenne fontos?
Ezért:
Ezen kívül egyre fejlettebbek az adatbázis-kezelők, és sok optimalizációt tartalmaznak. Pl. nyilvántarthat adatokat a mezőkben tárolt adatok változatosságáról, ami alapján megváltoztathatja a logikai kifejezések kiértékelési sorrendjét. De nem hiszem, hogy ezekre a nem pontosan ismert, feltételezett optimalizációkra kellene hagyatkozni.
MYSQL index
Szerintem alapvető hiánya az adattáblának egy olyan mező,amelyre Egyedi
indexet lehet generálni.Pl:[ sorszám ].Az instr VARCHAR(9) nem tudom mit takar.
Én (sorszam int) mezővel kezdtem volna.Erre jöhet a " CREATE UNIQUE INDEX sor_i
ON kot(sorszam)" ezután jöhetnek a mezők indexei Pl.a 'vevo','elado','datum'
Az SQL azt hiszem elég inteligens ahhoz,hogy a érdésnek megfelelő indexet használja.
Tehát szerintem a megoldás egy új oszlop beszúrása,ha meg tudod csinálni akkor az első helyre.Utána töltsd fel egyedi értékkel:sorszámmal,majd generáld meg az indexeket.Erre az időre kizárólagos hozzáférést kell biztosítanod.Sok sikert!
<Nincs cím>
kis pelda:
a beki oszlop erteke enum(be,ki,bejebb,kijebb)
erer lokok egy indexet az sokat segit.
Amugy olyan cuccokat erdemes indexelni amit a WHERE is tartalmaz es visszatero adatokkal van feltoltve.
udv. Oregon
ps.: nem vagyok egy sql guru, csak hobbi szinten fejlesztgetek.