ugrás a tartalomhoz

Szűrés két mezőre

zzrek · 2011. Már. 15. (K), 18.09
Sziasztok!

Mysql-ben nézegetem az adatbázisomat, és most meglepődtem egy felfedezésemen, és megoldást keresek.

Egy táblában van két varchar mezőm, mindkettő indexelve.
Ha egy egyszerű
EXPLAIN SELECT * FROM tabla WHERE uid1='1483094561'
parancsot adok, akkor az eredmény, hogy type:ref, possible_keys:uid1, key:uid1
De ha ezt vizsgálom:
EXPLAIN SELECT * FROM tabla WHERE uid2='1483094561' OR uid1='1483094561'
...akkor type:ALL, possible_keys:uid1,uid2 key:(NULL)

Ez ugye azt jelenti, hogy nem használta az indexet, ugye?
Miért nem? Mit tegyek, hogy használja?

Köszönöm a tanácsokat!
 
1

varchar?

Poetro · 2011. Már. 15. (K), 18.48
Ezek miért varchar mezők? Miért nem valamilyen int mező? Csak mert, akkor nagyobb lenne az esély hogy használja őket. Tudtommal (de javítsatok ki) van egy korlát, amekkora index mezőt egy query tud használni. Ezt ugye ha szám mezőket használunk számok tárolására, akkor sokkal jobban alakul, ugyanis egy 32 bites számot el tud tárolni a rendszer 4 bájton, míg ugyanekkora szöveghez 10 bájt szükséges. Amennyiben a szám 64 bites, akkor 8 byte szükséges számként tároláshoz, míg ha szövegként tároljuk, akkor 20 byte.

Amit még megpróbálnék, hogy olyan sorrendben tenném a lekérdezés mezőit, amilyen sorrendben az indexek vannak. azaz ebben az esetben:
EXPLAIN SELECT * FROM tabla WHERE uid1='1483094561' OR uid2='1483094561'
2

Köszi a tippeket

zzrek · 2011. Már. 15. (K), 19.09
Köszi a tippeket!
Azért nem int, mert külső forrásból származó azonosítók, és nem tudhatom biztosan hogy milyen a hosszuk, sőt azt sem, hogy tartalmaznak-e nem numerikus karaktereket, vagy bevezető nullát.
Kipróbáltam a cserét, de semmi változás :-(

(Ja, és kösz a színezést ;-)
3

Index hossz

janoszen · 2011. Már. 16. (Sze), 09.11
A MySQL-ben legjobb tudomásom szerint a max indexelhető hossz 1000 byte. Ha UTF-8-as stringet tárolsz, ráadásul a maximális hosszat foglalja le.
4

varchar(250)

zzrek · 2011. Már. 16. (Sze), 10.07
Sajnos nem tudom hogy hogy működik ez. Varchar(250)-es mezőkről van szó, UTF8, MyISAM, MySQL: 5.0.24a.
Ha az indexet fulltext-re állítom, akkor már egy sima EXPLAIN SELECT * FROM tabla WHERE uid2='1483094561' -ra is a type "ALL" lesz.
Ha a where részben több indexelt mezőről van szó, akkor az 1000 bájtos limit ezek összegére vonatkozik?

Most visszavettem a mezőhosszt varchar(150)-re, de a "WHERE uid1='1483094561' OR uid2='1483094561'" így is type:ALL-os maradt.

Lehet, hogy az a gond, hogy túl kicsi táblával próbálgatom? Vagy hogy "Null" érték is van a cellák közt? (mindjárt kipróbálom) (kipróbálatm, nem a NULL miatt volt)

Minden tippet köszönök, teljesen tanácstalan vagyok. Úgy érzem, hogy ez az SQL nagyon buta, ha ilyet csinál -- és ez arra utal, hogy valószínűleg valamit nagyon elnézek és/vagy sajnos nem értek hozzá.
5

A MySQL megkísérli a query-t

bb0072 · 2011. Már. 16. (Sze), 12.16
A MySQL megkísérli a query-t a legoptimálisabban futtatni, de minden queryben csakis egy indexet használ. (Azt amelyik a legoptimálisabb ahhoz a queryhez, vagyis amelyik használatával a legkevesebb sort kell átnéznie.) Ez nem csak az adatok szerkezetétől függ, hanem a pl. a tárolt adatok mennyiségétől, rekordszámtól is. Ugyanaz a query ugyanazon struktúrájú 2 különböző adatbázison képes lefutni úgy hogy más és más indexet használ. De hogy melyiket használja azt megmondhatod neki a USE INDEX -el.

Fulltext indexet ne használj, mert az kizárólag match-against-el működik, és még van néhány egyéb gyomorfájása is.
6

Amit még csinálhatsz, hogy

bb0072 · 2011. Már. 16. (Sze), 12.28
Amit még csinálhatsz, hogy leméred a query futási idejét USE INDEX-el és anélkül (például konzolon), hogy lásd mi a különbség. Véleményem szerint, megfelelően kis rekordszám mellett elképzelhető, hogy valóban az a legoptimálisabb lefutás, ha ehhez a queryhez nem használ indexeket.

Alapesetben ugyanis a programozónak csak annyi a dolga, hogy tesz indexet minden olyan mezőre ami where vagy order by részben szerepel, a többi a MySQL dolga.
7

Én is úgy gondolom

zzrek · 2011. Már. 16. (Sze), 14.06
Én is úgy gondolom hogy az lenne a jó, ha "a programozónak csak annyi a dolga, hogy tesz indexet minden olyan mezőre ami where vagy order by részben szerepel" de az alapján amit mondtál, elbizonytalanodtam. Az, hogy csak 1 indexet használ egy lekérdezéshez, az elég meglepő és kiábrándító. Az az érzésem, hogy ez esetben minden lekérdezéshez készítenem kell egy komplex indexet. Vagy tévedek? Más SQL-ek is csak 1 indexet tudnak felhasználni?
8

Szerintem csináld meg az

bb0072 · 2011. Már. 16. (Sze), 15.09
Szerintem csináld meg az időmérést, abból kiderül, hogy a MySQL jól optimalizált-e magától, vagy sem. Ha nem, akkor nézd meg, mi van ha többmezős indexet használsz (uid1 és uid2).

Más SQL-ek is csak 1 indexet tudnak felhasználni?

Fogalmam sincs. Ha valaki tudja, válaszoljon!
9

Köszi

zzrek · 2011. Már. 16. (Sze), 15.32
Köszi, kipróbálom. Kicsit tartok tőle, hogy én bénáztam el valamit, de akkor ezek szerint nem erről van szó, ez egy ilyen dolog. Köszi az infókat.