MySQL lekérdezés optimalizáció

Sziasztok!

Nem vagyok egy nagy DB expert, ezért egy mások számára nyilván triviális problémára szeretnék megoldást kapni.

Flottakövető rendszernél percenként kapunk adatot egy-egy jármű helyzetéről. Pár hónap alatt már ~2.000.000 rekord van a LOCATION táblában, ami ezeket az adatokat tartalmazza. A LOCATION tábla a VEHICLE táblához van kapcsolva, ez testesíti meg a követendő járművet, hárművenként olyan ~400.000 rekord van.

Az alábbi lekérdezés irtózatosan lassú: select l.* from VEHICLE v inner join LOCATION l on v.id=l.vehicle_id where v.id=? and l.creation_date = (select max(l2.creation_date) from VEHICLE v2 inner join LOCATION l2 on v2.id = l2.vehicle_id where v2.id=?)

Ez szolgálna arra, hogy egy adott VEHICLE legfrissebb (creation_date) LOCATION-jét lekérdezzem.

Van valami ötletetek, hogy miért van ez ennyire elk*rva? Gondolom több sebből is vérzik. Ti hogy csinálnátok?

Köszi,
M.

Ui.: MySQL MyISAM storage engine

Szerk: Nem tudom mennyit számít, de a LOCATION táblát folyamatosan insertek bombázzák (mp-enként 10 körül).

Hozzászólások

Külön location tábla minden járműnek nem megoldás?

A feladat: járművenként megkapni a legfrissebb location-t.

A location táblában 5 teljesen primkó adattípus van, illetve egy foreign key a vehicle táblára vehicle_id néven. Mindkét tábla rendkívül egyszerű.

A többi kérdésedre hirtelen nem tudok válaszolni, mert jelenleg nem férek hozzá a géphez.

VEHICLE
+ ID (bigint)
+ CODE (varchar2)
+ NAME (varchar2)

LOCATION
+ ID (bigint)
+ VEHICLE_ID (bigint -> vehicle.id)
+ LATITUDE (number - nem emlékszem, sima decimal adattípus)
+ LONGITUDE (number - nem emlékszem, sima decimal adattípus)
+ CREATION_DATE (date)
+ SPEED (number)

Fejből ment, talán nem teljesen pontos, de tényleg halál egyszerű.

Ismerős a feladat, nekem is volt hasonló feladatom. Én egy temp táblával oldottam meg a kérdést, persze nekem Delphi alól kellett ezt leprogramoznom, az pedig nagyon szeresse SQL-t...

Először kiüríti a tmp táblát
második lépésben lekérdezi a kocsikat egyesével
második query pedig lekérdezi a lefrissebb dátumot ahol az adott kamion azonosító egyezik az első query eredményével
majd kinyomja egy excel táblába

________________________________________________
http://kronosz.sinuslink.hu

location(vehicle_id, creation_date) vagy location(creation_date) index van? Önmagában az inner select gyorsan lefut?

És egyébként miért ilyen nyakatekert ez a query? Elég lenne egy select-join, dátum szerint csökkenő sorrendben, és az első sor kell, nem?

--
joco voltam szevasz

select * from location where vehicle_id = ? order by creation_date desc limit 1

és a creation_date -re tennék egy indexet.

Vagy pedig lenne egy last_location tábla, amit updatelnék amikor uj location érkezik.

szerk.: vehicle_id ÉS creation_date lenne egy közös indexben.

+1

Nekem is az tűnik logikusnak (db-ben nem annyira járatosnak), hogy a legutolsó értéket külön tároljuk, van ebben valami hiba? Vagy nagy terhelés utolsót és a log-ot is írni?

szerk.:
Látom lentebb, hogy nem időrendben jönnek az adatok, de sebaj, egy összehasonlítással eldönthető, hogy kell-e az "utolsók" tábla tartalmát frissíteni.

Ezzel vigyazni kell. A memory engine table lockot hasznal, ha triggerrel updatelsz egy memory tablat, akkor gyakorlatilag a trigger miatt iraskor gyakorlatilag az eredeti tabla is lockolodni fog. Igy az insertek nem fognak tudni READ LOCAL lock-ot hasznalni. Azaz fognak tudni, de gyakorlatilag ugyanaz lesz a hatasa a trigger-rel memory update miatt, mintha nem tudnanak. Nyilvan InnoDB-nel ez sokkal sulyosabb.

Ezt el lehet kerulni, ha a summary tablaban nem egy rekordod van, hanem n, es a trigger egy randomot updatel, igy a tenyleges last location-t egy max(last_location)-nel kapod meg, ami ha a summary tablaban indexelt a mezo egy olcso muvelet. Es persze a summary tabla pl. InnoDB, vagy barmilyen olyan engine, ami row level lockot tud.

A memory tabla replikacional is szivas, ha ujraindul valamelyik instanceod. Ha InnoDB-t hasznalsz, es eleg nagy a buffer pool, akkor mivel az write back cache-kent fog mukodni (persze megfeleloen nagy redo logokkal, ebbol kovetkezoen megfeleloen ritka checkpointokkal), akkor sokkal rosszabb nem lesz. Ha sok parhuzamos irasod van (a topicnyito azt mondja van), akkor pedig a memory tablan levo table lock miatt szinte biztos rosszabb lesz, mint az InnoDB. Nem azt mondom, hogy ez bizonyos esetekben nem egy jo megoldas, de vegig kell gondolni, hogy mikor mi tortenik, amikor adatbazishoz nyulsz.

Ha DB2-ről kérdeznél, mondanám, hogy használj table partition-t, azt éppen erre találták ki. Sajnos nem tudom, van-e MySQL-ben is ilyesmi.

Azt viszont mindenképpen javaslom, hogy a stackoverflow.com-on (is) tedd fel a kérdésedet, ott jó eséllyel kapsz választ...

UI: van: http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html
"A very common use of database partitioning is to segregate data by date. Some database systems support explicit date partitioning, which MySQL does not implement in 5.1. However, it is not difficult in MySQL to create partitioning schemes based on DATE, TIME, or DATETIME columns, or based on expressions making use of such columns..."

Dobj hozza show create table kimeneteket is minden tablarol. Es az explain extended utani show warnings kimenetet is, hogy lehessen latni mit csinalt belole az optimizer. Lehetseges meg, hogy lock contentionod van, es az insertek miatt varnak a selectek. Torolsz valamelyik tablabol? A concurrent_insert hogy van konfiguralva?

A location tabladon legyen olyan index, amiben a vehicle id prefix. A mysql nem fogja a VILID indexed hasznalni a joinhoz, mert abban a vehichle id nem prefix. En beletennem a creation date-et is, igy a belso selected location fele is using index lesz. Tehat (vehicle_id, creation_date)-re csinalj indexet, es mutass ujra explaint, illetve szamolj be arrol mi lett.

Szerk: most latom ezt mar irtak neked fentebb is. Veluk ertek egyet:).

Szerk2: ha a concurrent_insert 1-en van (default), es nem torolsz, akkor az insertek mindig read local lockot fognak hasznalni, tehat ez elvileg nem gond, mert a selecteket nem blokkoljak, csak egymast.

Én MSSQL-ben dolgozom, tehát lehet, hogy difi van My és MS között e téren.

Right joint használok, mégpedig a következőre:

Adva van két tábla legyen A és B, az A táblába vannak a cég rendeléseinek azonosítója (orderid, subid, subsubid) és a vevő adatai (customer, customeradress, city, stb) a B táblában vannak a csomagok, amik kimennek hozzá (colno), és szintén a rendelés szám (orderid, subid, subsubid)
Ha leakarom kérdezni, hogy egy adott rendelés alatt milyen collik vannak, akkor így teszem:

Select * from A right join B on (A.orderid = B.orderid) and (A.subid = B.subid) and (A.subsubid=B.subsubid)
where orderid='10099' and subid='1' and subsubid='10'

És így kiír nekem szépen mindent, hogy a 10099 1 10-es rendelés alatt milyen collik szerepelnek, utána meg kiválasztom, hogy éppen nekem mi kell pontosan.

szerk: hozzáteszem, az A táblában a rendelésszám, csak 1x szerepel, mígy a B táblában többször is előfordulhat, ez a kulcsa a dolognak.
________________________________________________
http://kronosz.sinuslink.hu

Van valami ötletetek, hogy miért van ez ennyire elk*rva? Gondolom több sebből is vérzik. Ti hogy csinálnátok?

van.

több adatbáziskezelővel, több projektben bizonyított tény, hogy ezt a feladatot nem érdemes/szabad a db layerre bízni, ha a performancia számít, és nem tartható kordában a histórikus entryk száma (kulcsonként 50-100 már sok)

- külön az aktuális értékeknek egy tábla (mindig a legutolsó adat van benne)
- külön a histórikus értékeknek egy logtábla (ez kb. a mostani táblád)

az egyszerűbb verzió szerint:

delete from actual where key = xxx
insert into actual ....
insert into historic ....
commit

vagy lehet kiolvasni az actual táblát, hogy update vagy insert kell. esetleg írni egy pl/sql függvényt, ami megcsinálja az egészet.

A commit nem ertelmezett dolog myisam eseten, de a tablastrukturakat nezve igazabol semmi okat nem latom, hogy ebben az esetben miert jo myisamet hasznalni. Amit irsz, az legegyszerubben egy after insert/update triggerel oldhato meg, ami egy summary tablaban frissiteni fogja a creation date-et, a az uj/modositott rekorde nagyobb, mint a summary tablaban levo rekord.

Szia!

A MyISAM sajnos azért van, mert nem ismertük eléggé a MySQL-t, amikor belevágtunk ebbe a feladatba, s ez volt a default.

Később mi is észrevettük, hogy ez nem volt jó választás és be is terveztük az InnoDB átállást, csupán még nem jutottunk el addig.

A kérdés, hogy tapasztalataid szerint mennyire problémás egy ilyen átállás? Tényleg elég egy ALTER TABLE, vagy vannak olyan dolgok, amivel hatalmasat lehet szívni?

Köszi,
M.

Vannak, a legtipikusabb, amibe szinte mindenki belefut, hogy lapozasnal count(*) tipusu lekerdezesek myisam-en nagyon gyorsak (az MYD headerjeben tarolja a mysql a record countot, es ezt folyamatosan frissiti), InnoDB-nel az MVCC miatt ez nem leheteseges, hiszem attol fuggoen, hogy egy tranzakcio mikor kezdodott, illetve mit csinalt eddig (hogy itt mi szamit az tranzakcio izolacios szint fuggo), az innodb mast fog mutatni az adott thread-nek, tehat ha nincs jol indexelheto where, ami alapjan szursz, akkor ez egy index scan lesz egy header elolvasasa helyett. Ha MyISAM specifikus dolgokat nem hasznalsz, mint pl fulltext vagy spatial indexek, akkor alter table utan funkcionalis problemaid nem lesznek, maximum teljesitmennyel kapcsolatosak. A default innodb parameterek modern hardveren eleg nevetseges teljesitmenyt fognak produkalni (pl. 5 MB-s redo logok, es 10 MB-s buffer pool), az innodb parametereinek a megfelelo hangolasaval az alapesethez kepest nagysagrendi novekedest lehet elerni.

Ennek az egész lekérdezésnek se füle se farka..

a) Amennyiben a ID ismert ez a lekérdezés hülyeség:
(select max(l2.creation_date) from VEHICLE v2 inner join LOCATION l2 on v2.id = l2.vehicle_id where v2.id=?)
Helyette:
(SELECT max(creation_date) FROM location WHERE vehicle_id = ?)

b) Összeségében az egész egy baromság mert mert semmi szüksgé join-tokra (amik eleve kölségesek, lassúk):
SELECT * from location WHERE vehicle id = ? AND creation_date = (SELECT max(creation_date) FROM location WHERE vehicle_id = ?)

Persze lehet valamit rosszul írtam mert ekkora gányolást régen láttam..

Jó lenne, ha normálisan írnád az SQL-eket, mert így nagyon gáz.. a kulcsszavakat nagybetűvel minden mást ajánlott kisbetűvel.. az aliasok is teljesen feleslegesek ezeknél a lekérdezéseknél.

A többi már az index-eken múlik...

a) +1
b) +1

creation_date -> index --> ott a pont :-)

De miért kéne nagybetűkkel írni az SQL utasításokat?! Az általam megfigyelt jelenség, hogy mindenhol szoknak le a nagybetűkről: körülményesebb gépelni! Sőt a táblanév lehet case-sensitive!!!

Attila, Perger
-----------------------------------------------------
"Az a szoftver, amelyiket nem fejlesztik, az halott!"

Azért kell normálisan írni az SQL-t, hogy se aki írta, se aki olvassa nem szopjon.
De ez nem csak a nagybetűkre vonatkozik, igazság szerint a fenti lekérdezést minimum valahogy így kell helyesen írni:

SELECT *
  FROM location
 WHERE vehicle_id = ?
   AND creation_date = (SELECT max(creation_date)
                                   FROM location
                                  WHERE vehicle_id = ?)

Minden más mód taknyolás.

>> Sőt a táblanév lehet case-sensitive!!!
Persze, mindent lehet, csak kérdés szabad-e. Ez tipikusan az a dolog (case-sensitive nevek), amit nem szabad, sok szopástól megkíméled magad.

Egyébként egy könyvben volt az a bevett szokás, hogy a táblaneveket PascalCase a mezőneveket kisbetűvel az SQL utasításokat meg nagybetűvel írta, merthogy így egyértelmű, hogy mi micsoda.

(Igaz, magam részéről kisbetűvel írom a táblanevet, igaz, nem mintha zavarna PostgreSQL alatt, MySQL-ről és a hülye case-sensitive fájlrendszerekről meg nem tehetek...)

----------------
Lvl86 Troll

Mondjuk úgy, hogy mondok neked case insensitive unixot. Persze, értem én, hogy GNU is not unix...

Egyébként értem én, hogy képtelen vagy elképzelni, hogy képes vagyok elfogadni ezen fogyatékosságot, csak épp a hasznosságát nem látom. Azon kívül, hogy egy átlagfelhasználónak meg kifejezetten szopatás.

----------------
Lvl86 Troll

Például Zend Framework az osztálynevek alapján keresi a php fájlokat és az osztálynév minden esetben ilyen: Package_Osztalynev. (még nem voltak "\névterek") Ez a Package/Osztalynev.php és ha nem ez a fájl neve, az nem lesz jó.

Maradjunk annyiban, hogy rendre szoktat és ez hasznos.

*facepalm*

valaki elmagyarázza neki mit jelent az "insensitive" szó, vagy tegyem meg én?

najó akkor: kedves zoner, az általad említett példa pont a szerinted überalles case-sensitive fs esetén tud hibázni, case-insensitive esetén nem

nyugi nem baj hogy összekeverted, az IT népesség 99%-ába tartozol ezzel (lásd: sj)

Ha valakit ez szoktat rendre es nem a szulei es a szakmai igenyessege nevelte arra, az mar veszett fejsze nyele...

(A nevterekkel torteno autoloadban meg kulon aranyossag, hogy a hosszu ideig irtas alatt levo include|require[_once]-ket hozzak vissza, csak use kulcsszoval gyakorlatilag.)

De amugy latom, nem nagyon fogtad fel a lenyeget:

Azt mond meg, miert jo az, hogy tudok Osztalynev.php es osztalynev.php nevu fajlt is letrehozni es hol van erre szukseg, amelyet semmilyen mas modszerrel nem lehet kulturaltan megoldani.

----------------
Lvl86 Troll

ez a gyökér hupper-mentalitás egyébként tettenérhető a shell-ekben, ahol a completion úgy van megoldva, hogy stringre matchel a könyvtárlistában, nem magukat a file-okat keresi (hogy miért, arra nincs normális ok)

ennek következménye az, hogy kényelmes case-insensitive fs esetén is nyomkodni kell a shift-et a szupcsi bash-nak, ha pl a Downloads dir-t írná be az ember

jól értem, az a problémád, hogy a shelled nem találja ki, hogy az éppen aktuális könyvtár milyen fs-en van, és ott számít-e a kis/nagybetű, és ezért nem jön rá magától, hogy a do-kezdetű begépelésed matchelne a Do-kezdetű entryre?

mert erre te sem tudnád megírni az algoritmust anélkül, hogy a shell ne tudja valahogy lekérdezni, hogy milyen az az fs...

nem a feladat mérete a probléma.

hozzá kell nyúlni egy api-hoz, ami kváziszabványként él, n különböző cég z különböző termékében. szerinted ha holnap megálmodod azt a rendszerhívást, ami egy könyvtárról megmondja, hogy az case insensitive-e, akkor hány év(tized) múlva lesz reális elvárás, hogy a bash-t futtató gépek 80%-án ez az api rendelkezésre álljon? szerintem alsó hangon 10 évről beszélünk...

hint: nem csak a linux az egyetlen unix a világon...

és hogy ez miért nem aktuális probléma a unix világában? mert az összes ma használatos unix összes fs-e case-sensitive... ez az egész "probléma" csakis és kizárólag a pc-n/dos-on/os2-n/winfos-on nevelkedett generációt érdekli.

> a shell honnan a szarból tudhatná?

várjál durván advanked algoritmus következik:

$ mkdir VlNagGyonOkOsakaTmonDaHUPon
$ mkdir vlNagGyonOkOsakaTmonDaHUPon || echo iam so insensitive
mkdir: vlNagGyonOkOsakaTmonDaHUPon: File exists
iam so insensitive

asszem az alapok mostmár világosak lehetnek

nem értem.

bármi, ami nem read-only művelet, az nem jó, hiszen
- kurvára rossz néven venném a shelltől, ha a háttérben bele-belepiszkálna a könyvtárakba, amikor én nem mondtam neki
- nem is biztos, hogy tud oda írni...

mellesleg, a fenti teszt nem is jó, mert létezik már a könyvtár, akkor hibázhat. és nem, nem lehet tudni, hogy van-e olyan könyvtár, mert hiába olvasod végig a könyvtár tartalmát, mire utána megpróbálsz létrehozni, addigra valaki a háttérben simán csinálhat egyet...

> - kurvára rossz néven venném a shelltől, ha a háttérben bele-belepiszkálna a könyvtárakba, amikor én nem mondtam neki

autoconf-ot ne nézz meg

> - nem is biztos, hogy tud oda írni...

$ ls -d library Library LiBrArY && echo mekkora durvasag
LiBrArY/ Library/ library/
mekkora durvasag

autoconf-ot ne nézz meg

na de az a rendes működés során ír a könyvtárba, ott nem lepődik meg az ember, ha hullik a forgács.
de egy read-only művelet (cd, meg ilyenek) közben ne terpeszkedjen már a shell sehova, maradjon a valagán.

ez kb. olyan, mint amikor a winword 6.0 nem indult el olyan gépen, amin a user a c: gyökerébe nem tudott írni. mert neki valami teszthez feltétlenül oda kellett kullantania egyet...

akkor ismét: nem létezik olyan readonly műveletsor, amivel user space-ből 100% biztonsággal a bash el tudná dönteni, hogy az adott fs case sensitive-e. readwrite algoritmust se tudnék megfogalmazni, ami versenyhelyzetektől teljesen mentes lenne, és szintén 100% biztonsággal megmondaná, hogy széna vagy szalma.

egy módja van ennek a kiderítésére: ha megkérdezi a bash valahogy az oprendszert, hogy mondja már meg, legyen szíves. csak erre jelenleg a unixokban nincs semmilyen mód.

de ha másképp látod, azzal sincs semmi baj.
írd meg a kódot, aztán majd mutasd meg.

én készséggel elfogadom hogy amit írtam, az csak 99%-os, viszont mivel a jelenlegi állapot meg 0%, így nekem ez elég (közben egyébként megoldódott a kérdés, végre insensitive a matching)

te meg sírjál nyugodt szívvel api-ért. lazán kapcsolódik: c++t vagy javát szereted jobban?

De meg mindig nem ertem, hogy egy kenyelmi funcio (mert ugye a tab completition az) miert kell a fajlrendszer kepessegeit firtassa.

Mar csak azert sem ertem miert kellene, mert ha pl. Downloads-t case sensitive FS-n kell leirni eleve kenyelmesebb, ha a do-ra is felajanlja. Egy string kisbetusse alakito algoritmushoz meg nem kell semmilyen extra API, maximum egy mai karakterkeszletet ismero lib.

----------------
Lvl86 Troll

- Masodszor meg az alapveto problema az volt, hogy miert nem az FS-tol kerdezi, hogy van-e olyan kezdetu fajl.

mert erre nincs api, amin ezt meg tudná a shell kérdezni.

jelenleg az egyetlen definiált directory olvasás/keresés művelet az opendir/readdir, amivel az egész könyvtárat lehet végigolvasni, hogy milyen nevű entryk vannak benne, aztán utána a shell matchelget magának, ahogy ő képzeli a világot.

sem olyat nem lehet kérni, hogy a matchelést csinálja meg a fs, sem pedig olyat, hogy vajon az fs case-insensitive-e.

lehetne ilyen apit definiálni. hajrá.

Nem akarok beszállni a háborúba, de..
.. a fájl nevek valahol String típusúak, így nem értem mi a baj bash-al, főleg, ha a unix fs-ek többsége case sensitive.
(nem hiszem, hogy a bashnak figyelnie kellene a használt fs tulajdonságaira)
.. szerintem elég nehéz találni értelmes példát találni, de ez az egész csak megszokás kérdése inkább, gyanítom a többségnek
teljesen magától érthető egy case sensitive fs unix alatt.

En meg nem ertem, hogy mit nem lehet azon erteni, amit Gabu mondott: miert nem az FS-re bizza a bash a fajlok kereseset es miert vezet be egy olyan megoldast amely nyilvanvaloan figyelmen kivul hagyja a fajlrendszerek kepessegeit.

"ha a unix fs-ek többsége case sensitive"

tobbseg != az osszes. Sot, ha szigoruan az unixokat nezzuk csak, valoszinuleg pont a kisebbseg.

----------------
Lvl86 Troll

> mit nem lehet azon erteni, amit Gabu mondott
Konkrétan ezt mondta:
"hogy stringre matchel a könyvtárlistában, nem magukat a file-okat keresi (hogy miért, arra nincs normális ok)"
De végre megértettem, hogy azt akarta mondani, hogy az FS-re (?) kellene bíznia a fájlok keresését.
Ezzel az a baj, hogy bármilyen szögből vizsgálja az ember: baromság.

1) Nem hiszem, hogy a kernelben lévő FS driver dolga a fájlnévre való szűrés megvalósítása..
.. ajánlom kérdezzétek meg egy konkrét fórumon: kernel.org.. akkor a "nem hiszem" konkrétan kiderül..
talán kompetensebbek nálam és Nálatok is..
2) A mountnál sok esetben meg tudod mondani, hogy miképp csatolja fel a fs-t.. szenzitíven, vagy sem..
3) A bash-nak is van manja olvasni csak tudtok: set completion-ignore-case on/off

Egyébként, hogy miért így csinálta meg: passz, sokszor van az ember úgy hogy nem tudja melyik a jó megvalósítás, ezt választotta/ták: ennyi.
Ilyen alapon millió egy programot lehetne szidni, nem csak unix-ost.

Ha netan megint idetevedne egy olyan AAPL-fan, aki nem ismeri a man parancsot, annak hasznos lehet:
man bash

completion-ignore-case (Off)
If set to On, readline performs filename matching and completion in a case-insensitive fashion.

Szinten ebbol a manbol (futo shellre):
shopt [-pqsu] [-o] [optname ...]
Toggle the values of variables controlling optional shell behavior. With no options, or with the -p option, a list of all settable options is displayed, with an indication of whether or not each is set. The -p option causes output to be displayed in a form that may be reused as input.
...
no_empty_cmd_completion
If set, and readline is being used, bash will not attempt to search the PATH for possible completions when completion is attempted on an empty line.
nocaseglob
If set, bash matches filenames in a case-insensitive fashion when performing pathname expansion (see Pathname Expansion above).
nocasematch
If set, bash matches patterns in a case-insensitive fashion when performing matching while executing case or [[ conditional commands.

Azert jo ez a hupmeme, Gabu becsulettel gyujti a sajat hulyesegeit is, bar mas neve alatt..

--
Always remember you’re unique, just like everyone else.

Igy is lehet terelni, de ettol meg megprobalkozhatnal egy icurka-picurka szakmai kontentet is belecsempeszni a hozzaszolasaidba.

Pl. hogy megis miert is "feature" a case sensitive FS es hol van szukseg van ra. Addig marad felesleges szopatas*.

(*Hulyegyerekek es trollok kedveert: az, hogy felesleges fassagnak tartom, barmennyire hihetetlen es elkepzelhetetlen, a napi ugyes-bajos dolgaimban egy cseppet sem okoz fennakadast ez _szamomra_.)

----------------
Lvl86 Troll

Nem azt kérdeztem, hogy az ASCII táblában mi van, hanem azt, hogy egy fájlrendszerben hol van ez gyakorlatban _kihasználva_, hogy az FS is így gondolkodik.

Tudod, értő olvasás. Ha már írtál egy könyvet, olvasni is megtanulhatnál ahelyett, hogy a hülyeségeid meg a pebkacot szajkózod itt jobbra-balra.

----------------
Lvl86 Troll

> egy fájlrendszerben hol van annak előnye, hogy ezt figyelmbe is veszi.

Attól 'case sensitive', hogy nem veszi figyelembe. Ahhoz meg hogy figyelembe vegye (case insensitive) kell valami kódtábla. Sok juzer, sok kódtábla. Sok fájl, sok kódtábla, problémás. Jobb, ha egy sincs (byte array).

ugy erzem, mintha egy kicsit elbeszelnenk egymas mellett, pedig probaltam elmagyarazni, hogy a kiindulo pontodban van a problema, ti. az irracionalis hisztid a case sensitive fs-ek miatt, meg az eroltetett 'mutasd meg, hogy hasznaljak ki a gyakorlatban', holott a feature szo azt (is) jelenti, hogy tulajdonsag, sajatossag, azaz igy talaltak ki, igy mukodik, igy kell elfogadni/szeretni/whatever. Szoval valojaban semminek nem kell kihasznalni, hogy pl. a /etc/hostname nem ugyanaz, mint a /etc/HOSTNAME, de mindennek figyelembe kell vennie, hogy nem ugyanaz. De orulok, hogy az en megertesi kepessegeimet kritizalod a tied elozetes self-check-je helyett... LOL

Az meg valtozatlanul pebkac, ha valaki Download-ot keszit pl. xfs-en, majd download-kent akar ra hivatkozni. Erre irtak fentebb _nagyon_helyesen_, hogy ha mar apu/anyu nem tudott egy pici rendre sem szoktatni, akkor majd ez segit egy kicsit... Ez a feature ugyanis nem az fs gyengesege, hanem a buta usere, es vissza is erkeztunk a kiinduloponthoz, ti. nem vagy eleg erett egy ilyen fs hasznalatara. Tudom, tudom, _te_ eleg erett vagy hozza, csak akkor tudnam, hogy miert hisztizel miatta... na idd meg a reggeli kakaodat, aztan szedd ossze magad.... LOL

Ennek a mellekszalnak reszemrol vege, ennyi volt a troll simogatas mara...

Deutsch: Ki a fasz az a Thomas Melia?

upsz, azt hittem az spl_autoload_register-t linkeled.
akkor viszont nem ertem, hogyan gondolod, hogy ezt hasznalhatnak a default implementaciot.
nagyon leegyszerusitve a Foo_Bar_Baz osztalyt. a Foo/Bar/Baz.php-ban kell keresni, erre a default implementacio nem kepes, o a Foo_Bar_Baz.php-t fogja megprobalni beincludeolni.

szerintem amivel osszekevered, az az, hogy a \Foo\Bar\Baz osztalyhivatkozast valoban a Foo/Bar/Baz.php helyen fogja keresni, de leven hogy a ZF (ertheto okokbol) meg nem hasznalja a nevterezest(a ZF2 mar igen), ezert nekik nem jo a default implementacio.

Tyrael

Akkor most meg azt a kort fusd meg, hogy mire valaszoltam.

En arra reagaltam, hogy a ZF case sensitive include-ol, a default impl meg mindig downcase-l, igy neki erdektelen, hogy a page a Page vagy a PaGe osztalyt keresed.

Ez esetben en el tudnam kepzelni, hogy a ZF (tekintve, hogy nem nevterezik) fallbackeljen a spl_autoload-ra, ha normal modon nem talalta meg a cuccost. Mondjuk ehhez fel kell adni az agyonmappazott szerkezetet, de hat valamit valamiert.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

ok, nekem ez nem volt egyertelmu az eredeti uzenetbol.
szerintem jobb igy, hogy megvan az 1-1 hozzarendeles az osztalynevek, es a fajlnevek kozott, de nyilvan akinek nem tetszik a default, az olyan autoloader(eke)t allit be amilye(neke)t csak szeretne.
amugy ugy tunik hogy a PSR-0 lesz a kvazi ipari standard:
http://groups.google.com/group/php-standards/web/psr-0-final-proposal?p…

ps: nem egeszen ertem, hogy mire ez a flegma stilus.

Tyrael

> nem mintha zavarna PostgreSQL alatt,
Akkor zavarna, ha nagybetűvel írnád, vagy vegyesen,
mert akkor minden azonosítót (táblanév, oszlopnév, stb) idézőjel (") közé kell tenni az SQL utasításokban, ami egy idő után nagyon zavaró, különösen, ha valamiért esc-pelni kell az utasítást.
Amúgy meg, legalábbis postgres szempontjából semmi köze a FS-nek a objektum nevekhez.

A Location-ben az ID nem időrendi sorrendben növekszik?
Amúgy az előttem szólóhoz kapcsolódva, a joinok tök feleslegesek, legalábbis a subselectben...

select * from vehicle,location when vehicle.id=location.vehicle_id and location.id in (select max(id) from location group by vehicle_id)

Hú régen SQL-eztem, de valahogy így csinálnám...

váltani pl postgresql-re.
bocs.
én is nagy mysql ventillátor (gyengébbek, azaz gabu kedvéért: fan) vagyok, de mióta semmi érdemleges nem történt az 5.0 óta, pgsql-t használok az új hekkelésekhez.

--
"SzAM-7 -es, tudjátok amivel a Mirage-okat szokták lelőni" - Robi.

5.1-ben tabla particionalas pl eleg regota vart feature volt, 5.0 es 5.1 kozott is orasi a kulonbseg, nemhogy 5.0 es 5.5 kozott. Ezeknek a javaresze nem a fejlesztok altal hasznalt featureoknel keresendo, hanem a motorhazteto alatt, de ezt a release notesban ezeket le szoktam irni:).

Hello!

Ugyan nem tűnik nagy dolognak,de ha tudud hogy milyen adatokat akarsz megkapni egy lekérdezéstől akkor szerintem a * is felejtős a select után. Írd ki hogy melyik mezők adataira vagy kíváncsi. Ez mondjuk első ránézésre pitiáner dolognak tűnhet ,de szerintem egy kb. 2.000.000 soros táblánál már számíthat valamit a végeredménybe.

Üdv.

Nos:

1. Tudom, hogy gány, tényleg nem vagyok DB szakértő, s most az itt felvázolt dolgoknak utánaolvasván már látom és értem, hogy miért takony.
2. A (vehicle_id, creation_date) index csodákat művelt, az eddig rohadás-lassú elérés most teljesen élvezhető sebességű lett: köszönöm a tanácsot.
3. Természetesen amint lesz rá lehetőségem, átírom magát a lekérdezést.

Köszönöm a sok segítséget mindenkinek, de különösen petyának.

M.

külön táblában tárold a vehicle aktuális (legutóbb kapott) pozícióját. Ha új adat jön, akkor replace into-val tedd be ebbe a táblába, és legyen a táblán egy before update trigger ami berakja az előző location-t a mostani location tábládba (amiben historikusan megvan minden adat). Ezzel persze denormalizálod az adatbázist de ezzel sztem ebben az esetben semmi baj nincs.

(lehet h ezt már írták fentebb, nem olvastam el minden hozzászólást)

hatulrol elore:
myisam nem birja jol, ha gyakori insert/update mellett vannak lassu select lekerdezesek (nem csak az iras tartja fel a select-et, de forditva is lasd http://blog.scoutapp.com/articles/2009/10/09/choosing-between-the-mysql… )
szoval javasolnam hogy konvertaljatok innodb-re.

lehet hogy lehetne az uzleti logika reszen is javitani, nem biztos, hogy szuksegetek van megtartani (vagy ugyanabban a tablaban megtartani) az osszes regi rekordot, ha megis, akkor meg mindig lehet esetleg particionalason gondolkozni( http://dev.mysql.com/doc/refman/5.1/en/partitioning.html ).

a query egyreszt azert borzaszto lassu, mert van benne egy dependent subquery ( http://dev.mysql.com/doc/refman/5.1/en/correlated-subqueries.html ), ami azt jelenti, hogy a select max() os lekerdezes az eredeti eredmenyhalmaz minden sorara le fog futni.
atirnam joinra:

SELECT * FROM (SELECT id, MAX(creation_date) as creation_date FROM location
GROUP BY id) as l
INNER JOIN VEHICLE as v
ON l.vehicle_id = v.id

(nem teszteltem, de nagyjabol jonak kellene lenni)

meg kell nezni, hogy az l.vehicle_id es v.id oszlopokon van-e index, ha nincs, akkor letrehozni, illetve van egy tippem, hogy a mysql query optimizer filesort-ot akarna csinalni a join miatt (ellenorizzetek le a query-t EXPLAIN elotaggal futtatva, ha nem ir using filesort-ot az extra mezoben, akkor jo, ha ir, akkor FORCE INDEX-szel meg kell neki mondani, hogy hasznalja az indexeket: http://dev.mysql.com/doc/refman/5.1/en/index-hints.html)

ha innodb-re migralnatok, akkor ne felejtsetek el legalabb az innodb_buffer_pool_size-t megfeleloen beallitani.

szerk: most latom, hogy nem az osszes autohoz, hanem csak a megadotthoz kell az utolso datum, ebben az esetben a group by kivalthato egy order by creation_date desc limit 1-gyel, ha szeretned hogy hasznaljon a creation_date-re indexet, akkor ne feledd el az indexet is desc-kent felvenni (index alapjan csak akkor tudsz rendezni, ha az index abban a sorrendben volt letrehozva, ahogy te szeretned rendezni. nyilvan)

Tyrael

Az adatbázisokat akkora adatmennyiségekre tervezték, ami nem fér be a RAM-ba. A te adataidból kb 1 év 1gb. Vennek 32gb ramot, az adatokat beérkezés szerint log fajlba irnam, operative meg jarmuvenkent tombbe. A kereses meg linearis vegigolvasassal is verni fogja az adatbazist, de ido szerint binaris fat is epithetsz.