ugrás a tartalomhoz

Összetett kulcs

aspirany · 2008. Júl. 12. (Szo), 10.08
Sziasztok!

Lehet hogy elég amatőr a kérdés (sőt biztos); Mikor alkalmazzak összetett indexet, illetve mikor szimplát.


Köszönöm a válaszokat
 
1

Addatszerkezet

janoszen · 2008. Júl. 12. (Szo), 11.33
Például akkor, amikor az adatszerkezet megköveteli. A leggyakoribb használata (tudomásom szerint) a unique key, de el tudom képzelni, hogy foreign key relációban is szükség van rá, amikor két kapcsolódó adatmezővel akarsz ilyet csinálni. Hogy keresésileg mikor-mennyiben segít, azt nem tudom megmondani, abban nincs akkora tapasztalatom. Érdemes nézegetni a query végrehajtási tervét, hátha abból rájösz.
9

nem igazán

Hodicska Gergely · 2008. Júl. 13. (V), 09.00
Unique key esetén persze lehet, hogy szükséged van rá, de nem ezt nevezném tipikus felhasználásnak. MySQL esetén a foreign key automatikusan indexet jelent (bár ez talán a legtöbb DB esetén így van, különben nem tudna egy join túl hatékony lenni).

Összetett indexre általában lekérdezések gyorsításához van szükség. Amire mindig érdemes figyelni, az a balról jobbra szabály: pl. az (a,b,c) indexet tudja használni a DB akkor is ha (a,b) vagy ha csak (a) indexre van szükséged.

Amit ilyenkor még érdemes lehet figyelembe venni, hogy ha mondjuk az indexed minden mezőt tartalmaz, amire szükséged van a lekérdezéshez, kivéve mondjuk egy, akkor érdemes azt is hozzácsapni az indexhez (ezt hívják covering indexnek), mert ilyenkor a lekérdezés kiszolgálásához szükséges minden infó benne van az indexben, és nem kell még külön a táblából is beolvasgatni.

Ebben a témában még megfontolandó hogy adott esetben ne mesterséges indexet (surrogate key) használjunk, hanem valamilyen természetes (akár összetett) kulcsot használjunk, ez főleg InnoDB esetén lehet érdekes, ahol a primary key egy clustered index (e szerint vannak fizikailag letárolva az adatok, az index levelei maguk az adatsorok), ezért a primary key szerinti elérés nagyon gyors.


Üdv,
Felhő
2

Amikor összetett a szűrés

siposa · 2008. Júl. 12. (Szo), 14.17
Például:

create table ANYAGFORGALOM (
  UZEM integer not null,
  BESZALLITO integer not null,
  ANYAG integer not null,
  MENNYISEG integer not null,
  Primary Key (UZEM,BESZALLITO,ANYAG)
);

select * from ANYAGFORGALOM where UZEM=?;
select * from ANYAGFORGALOM where UZEM=? and BESZALLITO=?;
select * from ANYAGFORGALOM where UZEM=? and BESZALLITO=? and ANYAG=?;
Ebben az esetben egy összetett indexed van, ami a fenti három lekérdezésnél használható. De ha ilyen lekérdezéseket is szeretnél:

select * from ANYAGFORGALOM where BESZALLITO=?;
select * from ANYAGFORGALOM where BESZALLITO=? and ANYAG=?;
akkor kell egy másik index is, a kulcsot ugyanis nem tudja használni:

create index IDX_AF_BESZ_ANY ON ANYAGFORGALOM (BESZALLITO,ANYAG);
A tanulság annyi, hogy a futtatott lekérdezések határozzák meg, milyen indexekre van szükséged.
3

Biztos?

janoszen · 2008. Júl. 12. (Szo), 15.59
Biztos ez? Ez azt jelentené, ha egy olyan motort csinálok, aminél mondjuk 20 mezőre lehet változó paraméterekkel szűrni, akkor nem fogja az egyes oszlopokra tett indexeket használni? Azért ez elég durvának hangzik.
4

normalform

js · 2008. Júl. 12. (Szo), 16.39
Szerintem az a húsz mező legalább 3, de inkább 8 táblából fog jönni. Az összetett index akkor kell, amikor a query-kben pontosan azokra a mezőkre keresel. Persze nem muszáj indexelt mezőre keresned (ami akkor is előfordulhat, ha összetett index belsejében már le van indexelve, de önmagában nincs), ha van idő. A sok indexet is karban kell tartani, meg tárolni is kell.

Azonban, ha teljesen kihasználod az összetett indexedet, és még további értékekre is szűrsz, akkor azért egy normális SQL szerver optimalizál.
5

Normálform

janoszen · 2008. Júl. 12. (Szo), 16.53
Asszem akkor vesztettem el a hitemet a normál formákban, amikor a MySQL 62 join per query limitjét túlléptem. :] Amikor az ember egy olyan keresőmotort ír, aminek közel száz féle paraméter alapján tetszőleges mezőkkel kell tudnia szűrni, akkor egyszerűen már nem életszerű ennyire normalizálni. És ilyenkor merül fel az említett kérdés.
7

Kukka tutti

siposa · 2008. Júl. 12. (Szo), 18.18
Biztos. Próbáld ki EXPLAIN-nel.
Viszont nem azt jelenti, hogy hogy ne használná a motor az egy-egy oszlopra tett indexedet. Csak ha jellemzően több oszlopra szűrsz, akkor (tudtommal) hatékonyabb, ha egy összevont indexet használsz. Viszont mindig csak az index elejétől tudja felhasználni az értékeket.
8

Köcce,

janoszen · 2008. Júl. 12. (Szo), 18.59
Köcce, ez volt a sejtésem. Csak kicsit furcsállottam és a jelen helyzetben elég szomorú vagyok az adatbázis-szerkezetemet illetően. :) Az a bajom, hogy hiába nézek meg explainnel valamit, annyi féle képpen tud szűrni a júzer ahány féle képpen csak akar és még jellemző szűrés sincs feltétlenül.
10

kontrol

Hodicska Gergely · 2008. Júl. 13. (V), 09.12
Azért ez teljesen nem igaz. Valamilyen szinten a kezedben van a kontrol, hogy milyen felületet adsz a user kezébe. Pl. azt nyugodtan mondhatod, hogy kocsi típust meg kell adni, de legalábbis valamilyen fajta jó kis szűrő mezőből valamelyiket kelljen megadni. Plusz a weben általában mindig jó dolog az, hogy lényegesen több az olvasás, mint az írás, ezért lehet valamilyen szinten pazarlóan bánni az indexekkel, bár arra figyelned kell, hogy ha túl sok féle index van, akkor ezzel lassítod némileg a lekérdezést, mert macerásabb a DB-nek kitalálni az optimális lekérdezési tervet (bár MySQL esetében ez valószínűleg nem annyira jellemző).

Szintén érdemes arra figyelni, hogy nem minden mezőre érdemes ndexet tenni, pl. az ajtók számának a kardinalitása az elég kicsi, nem lenne elég szelektív az index, ezért nem is használná a DB, csak feleslegesen van karbantartva. Ez alól kivétel lehet egy olyan mező, mint pl: status('processed', 'unprocessed'), ahol a kardinalitás kicsi, de 'unprocessed' státuszú sorból adott esetben nagyon kevés van a 'processed'-hez képest (erről a DB tart nyilván statisztikát), ezért mégis fogja használni az indexet.


Üdv,
Felhő
6

Köszönöm

aspirany · 2008. Júl. 12. (Szo), 17.45
Köszönöm a hozzászólásokat, okosabb lettem.

Köszi.
11

Alárendelt mezők

vbence · 2008. Júl. 13. (V), 10.44
Egy aspektus, ami még nem volt leírva konkrétan: ha lekérdezések gyorsításáról van szó végig kell gondolni, hogy vannak-e egymásnak alárendelt mezők, mint például ország > város, azaz, ha valaki Memphisben keres autószervízt, akkor nem lesz mindegy neki, hogy ez az USA beli Memphis lesz-e vagy az egyiptomi.

Máshogy megközelítve a dolgot: a lekérdezések egy adott pályán keresztül keletkeznek a webalkalmazásodban. Egy tipikus blognál a főoldalon szeretnéd látni a 10 legújabb bejegyzést. Ez ugyebár egy index a "létrehozva" mezőre. Egy tömeges blog szolgáltatónál viszont semmi érterlme ennek a querynek. Ott mindig az adott blog 10 legújabb bejegyzésére vagy kíváncsi. Itt érdemes egy összetett indexet bevezetni: (blogid, létrehozva), ekkor először szétválogatod blogok szerint a bejegyszéseket, és asztán (ezen belül) dátum szerint tartod nyilván.