Hirdetés

2024. május 1., szerda

Gyorskeresés

Útvonal

Fórumok  »  Szoftverfejlesztés  »  SQL kérdések (kiemelt téma)

Hozzászólások

(#1601) Sk8erPeter válasza pittbaba (#1600) üzenetére


Sk8erPeter
nagyúr

A látatlanbant arra írtam, hogy most nincs időm kipróbálni... :U

Sk8erPeter

(#1602) pittbaba válasza Sk8erPeter (#1601) üzenetére


pittbaba
aktív tag

Rendben :) az Explain kimenetét majd mutatom, ha egyszer kikergeti.

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1603) pittbaba válasza Sk8erPeter (#1599) üzenetére


pittbaba
aktív tag

Az explain kimenetéből mire vagy kíváncsi? Nem tudom copyzni a kezelőprogrammal sajnos, de ami fontos azt bepötyögöm.

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1604) modder válasza pittbaba (#1596) üzenetére


modder
aktív tag

kíváncsiságból én is feltettem notin mysql-be betöltöttem, és elkezdtem futtatni a lekérdezésedet. Nem tudtam végigvárni :D

1) Ez egy viszonylag normalizált adathalmaz, de nem feltétlenül lesz jó keresések szempontjából

2) mivel az adatbázis csak lekérdezésre lesz használva, simán megcsinálhatod, hogy létrehozol különböző táblákat, amik a keresést megkönnyítik: a relációkat denormalizálod, azaz egy adat, és az adatok közötti függőségek többszörösen lesznek letárolva. Ezzel azt nyered, hogy gyorsabban fogsz tudni keresni.
A "csak lekérdezéseket" azért emeltem ki, mert így nem kell majd azzal foglalkoznod, hogy az újonnan beszúrt adatok elrontják-e az adatbázist. Például az egyik táblába beszúrod, de a másikba elfelejted, satöbbi.

3) Igen, az indexelés, amit már említettek. A megálló nevére rá kell tenned egy indexet mindenképpen, ha így keresel, viszont nem hiszem, hogy SQLiteban van fulltext index: azaz szövegen belüli indexelés. Mivel LIKE %valami%-kal keresel, mindenképpen be fogja olvasni a rekordot, belemászik a szövegbe, és rákeres a szövegrészletre, szóval hiába indexeled, semmit nem fog érni. Max akkor, ha tökéletes egyezést keresel.
Többi indexelés:
-- stops.stop_id elsődleges kulcs, állítsd be annak, vagy tegyél rá egy indexet;
-- stop_times.trip_id -ra és stop_times.stop_id -ra külön-külön tegyél egy indexet;
-- trips.trip_id -ra tegyél egy indexet
azért ezekre, mert ezek azok az oszlopok, amik mentén te joinolsz, és ezek által az id-k alapján fog keresni az adatbázis.

ezekkel az indexekkel nekem a keresés 3 másodperc alatt lefutott laptopon. telefonon nem tudom milyen lesz...

Konkrétizálva:
Te most azt csinálod, hogy rákeresel a megálló nevére, majd megálló id alapján groupolod egy másik tábla oszlopa alapján, hogy ha egy utcában több megálló is van, azokat is megkapd. Ezzel még csak a megállókat találod meg, de nem nyersz információt az áthaladó trippekről. Az információ amire valójában szükséged van az a megálló_neve, megálló_id.

Ehhez képest te összejoinolod mind a három táblát. tegyük fel, hogy a stops táblából megtalálja a megfelelő sorokat amik pl az Örs vezér tere-re stimmelnek, ez lesz pl 10 sor, akkor szépen elkezdi végigkeresni a másik két táblában a hozzájuk tartozó sorokat, de a trip_id és a departure_time nem fog információt hordozni, mert groupoltad az egészet stop_id alapján, szóval egy megállóhoz csak egy trip_id-t fog kiadni... szóval ez így teljesen rossz.

Ami neked kell ebben az esetben:
SELECT stop_name,stops.stop_id FROM stops WHERE stops.stop_name LIKE '%Örs%' GROUP BY stops.stop_id

Viszont te GPS alapján akarod megtalálni, ez is jó lesz. Indexelned kell a stop_lat és stop_lon mezőket, és lekérdezed úgy, ahogy írtad. Csak a megállót! Akkor felhasználó kiválasztja a pontos megállót, így az átmenő trip-eket már csak az alapján kell keresned (fölösleges a közelben lévő megállókon átmenő tripeket is megkeresni).

Átmenő trippek:
SELECT * FROM `stop_times` WHERE stop_times.stop_id = valami and `departure_time` > "06:00:00"

Optimalizálás:
Visszatérve ahhoz, amit a legelején írtam a denormalizálásról. Nekem ezek a lekérdezések a belinkelt adathalmazon elég gyorsan lefutottak, de telefonon lehet, hogy más lesz a helyzet. Először próbáld ki rendesen indexekkel, hogy milyen eredményeket kapsz, és ha nem jók, akkor el lehet kezdeni szétdarabolni pl. a stops táblát 10 külön táblára, ezt hívják particionálásnak. Feltéve, hogy az SQLite van olyan intelligens, hogy nem olvassa be a memóriába az egész adatbázis fájlt, hanem beindexeli hogy melyik tábla hol kezdőik a fájlban, ezzel rendesen meg tudod gyorsítani a dolgokat.

Például szétdarabolod a stops táblát 10 táblára a stop_name szerint egyenletes eloszlásban, alfabetikusan növekvő sorrendben. Amikor név alapján akar keresi, tudni fogod egyből, hogy melyik táblában keress, mert tudod, hogy melyik tábla mettől meddig tartalmaz stop_name elemeket. Ez ugye csak név alapján keresésnél hasznos, úgy ha a felhasználótól elvárod, hogy a begépelt megállónévnek az eleje egyezzen valamelyik megállónévvel.

A stop_times feldarabolása. Mivel ez a tábla rohadt nagy, ezzel is tudsz nyerni időt. Én a stop_id alapán darabolnám fel szintén alfabetikusan hasonlóan ahogy az előbb írtam, el tudod dönteni már a stop_id alapján, hogy melyik táblában keress.

miért stops.stop_name és stop_times.stop_id alapján darabolj, és ne pl stops.stop_lan és stop_times.departure_time alapján? Azért mert az SQLite valószínűleg BTREE indexelést alkalmaz, ami nagyon jó intervallum keresésre. Alkalmazható számon, dátumon, talán még szövegen is! Viszont nem találtam , hogy lenne SQLiteban hash indexelés, ami arra jó, ha szeretnél megtalálni egy elemet konkrét értékkel. Ilyen az, amikor id-k alapján joinolsz. Amikor meg akarod keresni az adott stop_id-n áthaladó járatokat a stop_times táblában adott időponton belül, akkor megkönnyíted az adatbáziskezelő dolgát azzal, ha a particionálással 200e sor helyett csak 20e-ben kell keresnie.

Persze ez csak elmélet. az egész attól is függ, hogy a stop_times táblában először intervallumkeresést hajt végre az időpontra, és utána választja ki stop_id alapján a sorokat, vagy fordítva, de ezt már nem tudom, ki kell próbálni.

Azért jó lehetőség ez az adathalmaz optimalizálásra, mert nincsenek komplikált lekérdezések, csak egy-két féle, így ki lehet alakítani úgy a struktúrát, hogy ezeknek teljesen megfeleljen. Még ami eszembe jutott, hogy az adatbázisok általában elsődleges kulcs szerint teszik sorrendbe az adatokat fizikailag. Szóval ha a stop_times táblában (stop_id, trip_id) -t adsz meg elsődleges kulcsnak ebben a sorrendben, akkor megegyszerűsítheted az adatbáziskezelő dolgát, amikor stop_id alapján keresel, mert az ugyanahhoz a stop_id-hoz tartozó rekordok egymás mögött lesznek elhelyezkede, tehát szekvenciálisan gyorsan ki tudja olvasni az összeset.

De amúgy az is lehet, hogy simán az indexekkel tökéletesen gyorsan fog működni telefonon is, és az egész novella, amit leírtam teljesen fölösleges :D

(#1605) trisztan94


trisztan94
őstag

Sziasztok!
MsSql-be szeretnék nagy stringet, akár 10.000 karaktereset bevinni. Eddig ntext adattípust használtam, de több helyen is olvastam, hogy a nvarchar sokkal jobb, biztonságosabb. Ez igaz? A baj vele az, hogy az nvarchar az 4000 karaktert engedélyez maxon, míg az ntext az akármennyit (ha jól tudom).
Mit lehet használni ezeken kívül?

Köszi,
T

https://heureka-kreativ.hu

(#1606) pittbaba válasza modder (#1604) üzenetére


pittbaba
aktív tag

Wow! Köszönöm a rengeteg infót, átrágom rajta magamat részletesen is.
Első körben annyit, hogy azért lenne jobb a három tábla összekapcsolása, mert nekem GPS alapján az lenne jó, ha a a lehetséges járatnevek jönnének ki, ne kelljen megállót választania külön. Általában az ember azt tudja mire akar, mire kell felszállni és nem a megálló pontos nevét.

A group-ban teljesen bizonytalan voltam, azt köszönöm hogy tisztáztad a fejemben.
Az indexelésekkel kezdem, majd a stop_times feldarabolása lesz következő lépés az optimalizálás terén, én is azt találtam jónak,ha stop_id alapján szedem széjjel.

Még egyszer nagyon köszönöm! Ha bármilyen ötleted van még ,írd meg.

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1607) modder válasza pittbaba (#1606) üzenetére


modder
aktív tag

Értem, igazad van. Ezt már nincs kedvem végiggondolni, hogy pontosan hogyan lenne érdemes megcsinálni a kereséseket úgy, hogy a legközelebbi olyan megállót adja meg, ahol adott járat szám megáll, de szerintem adtam ötleteket. A lényeg, hogy mindig jól gondold végig, hogy mi kell, és fölöslegesen ne joinolj táblákat, fölösleges infot ne tegyél bele a selectbe.
Ja, az indexelést se állítsd be minden oszlopra, hátha kell alapon, mert az plusz tárhely, és nem fog mindig gyorsulást okozni a lekérdezésekben.

A tábladarabolással kicsit elszaladt velem a ló, csak akkor kezdj bele, ha látod, hogy egyébként lassúak a lekérdezéseid. Szívesen!

(#1608) martonx válasza pittbaba (#1606) üzenetére


martonx
veterán

Én is belebeszélhetek? Koncepcionálisan hibáztál.
Ne pöcsölj SQLite-al, egyszerűen nem erre való. Az egész DB-t told fel valahova a felhőbe, tegyél rá egy webszolgáltatást, vagy web api-t, és az android-os alkalmazásod meg hívogassa azon keresztül. Most komolyan te egy 600-1000 mhz-s kis fos telefon procitól várod el, hogy többszázezer soros, join-olt SQLite db-ből találjon meg bármit is pillanatok alatt? Indexelheted ezt akárhogy, akkor is megfőzöl egy kávét, amíg szegény kis proci végignyálazza akár csak az indexeket.

Én kérek elnézést!

(#1609) modder válasza martonx (#1608) üzenetére


modder
aktív tag

Ez egyébként teljesen igaz. csak akkor éri meg letölteni a telefonra az egészet, ha nincs mobilnete valakinek. Amúgy meg kíváncsi volnék, hogy hot fut a select telefonon :U

(#1610) Jim-Y válasza martonx (#1608) üzenetére


Jim-Y
veterán

Csak ha nincs az embernek mobilnete?

Én valahol a kettőt ötvözném, alapból egy webszolgáltatás lenne, amit mobilnettel teljes értékűként lehetne használni, de pl lehetne olyat, hogy az ember letöltse lokális adatbázisba az őt érdeklő járatokat, így offline is lehetne követni azokat a járatokat amit az ember használ.. talán..

(#1611) pittbaba válasza Jim-Y (#1610) üzenetére


pittbaba
aktív tag

Igen, ez lesz a megoldás erre, offline kevesebb szolgáltatás...

Sajnos valóban egy kvnyi idő egy lekérdezés még így is, darabolnom kell, vagy egyszerűsíteni.
Turista fejjel gondolkozok. Annak lehet nem megy a mobilnetje itthon, ezért akarom vmi offline módon megoldani.

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1612) Andoidtibi


Andoidtibi
csendes tag

Helló jó estét ! valaki valamit erre a problémára tudna valamit mondani? Válaszotokat előre is köszönöm

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOT NULL) ENGINE = myisam' at line 1

(#1613) modder válasza pittbaba (#1611) üzenetére


modder
aktív tag

ha csak egy szimpla szelektet csinálsz a stop_times táblában pl az időpontra vagy a stop_id-ra vonatkozóan az is lassú? Miután beállítottad az indexelést, újra betöltötted az adatokat a táblába? Azért járj utána egy kicsit hogyan működik az SQLite, ha nem töltötted be újra az adatokat, lehet nem is építette föl az indexet.

(#1614) McSzaby válasza Andoidtibi (#1612) üzenetére


McSzaby
őstag

:DD

[ Szerkesztve ]

#ThankYouSirAlex #ThankYouLouis

(#1615) pittbaba válasza modder (#1613) üzenetére


pittbaba
aktív tag

Szia!

Igen, pont ezzel kísérleteztem az elmúlt órában, hogy külön vettem a lekérdezéseket megnézem mi mennyi idő, de sajnos egy sima alap select is 10-30mp míg lefut a fájlban, nincs más választás.
Az indexel kapcsolatban sajnos nem értem a kérdésedet? Betöltöttem az adatokat? (Azok benne vannak már az indexelés előtt :D )
Hogy érted ezt?

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1616) modder válasza pittbaba (#1615) üzenetére


modder
aktív tag

hát az, hogy a csv-t szépen betöltötted az adatbázisba korábban. Utána ahogy ajánlottuk rátettél a különféle mezőkre indexeket. Ez gyorsított valamit a dolgon? Arra akarok kilyukadni, hogy lehet nem fogja indexelni a már bent lévő adatokat, hanem ki kell ürítened a táblákat és újra betöltened ahhoz, hogy szépen felépítse az indexeket.

De ez csak egy erős tipp, egyáltalán nem értek az SQLitehoz :))

[ Szerkesztve ]

(#1617) pittbaba válasza modder (#1616) üzenetére


pittbaba
aktív tag

szerintem semmit sem gyorsított, valószínűleg ezért.. nem is értettem hogy működhet ilyen gyorsan az indexelés.. most már értem :) tábla létrehozáskor kell indexelni és úgy nyomni a konvertálást. Akkor belepötyögöm a konverter appba, hogy indexeljen és lefekvés előtt elindítom, hátha gyorsabb lesz a db.

Szerinted ha csinálok egy selectet where nélkül, összejoinolva a táblákat, majd a kimenetet feldolgozom úgy, hogy építek belőle egy újabb összegző táblát az nagyon gáz lesz, vagy az is egy lekérésnyi időt vesz majd igénybe? Nem tudom ez a része hogy működik.

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1618) Ablakos válasza pittbaba (#1617) üzenetére


Ablakos
őstag

Milyen eszközt használsz az adatbázis szerkesztéséhez?

(#1619) pittbaba válasza Ablakos (#1618) üzenetére


pittbaba
aktív tag

SQLIte

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1620) pittbaba


pittbaba
aktív tag

Sziasztok!

Na a fentebb említett problémával még mindig küzdök, nézem mi lehetne jó megoldás. Meguntam a 10 perces lekéréseket, serveren tesztelnék sebességet mysql-el hogy tudjak haladni, viszont a GTFS adatbázisát sehogy nem bírom betolni a távolni server adatbázisába.
Sajnos sima havidíjas tárhelyem van, semmi ssh lehetőség, így nem tudom megoldani azt, hogy a 150 mb-os adatbázist beimportáljam. A phpmyadmin lenne az egyetlen lehetőségem, de az sem tudja fogadni a 120 megás stops_times.txt-t. Csináltam az itthoni lomhább serveren egy adatbázist a GTFS-ből, SQL formátumban exportáltam, ezt a fájlt szeretném valahogy a távoli serverbe bepasszírozni, milyen megoldásokat tudtok ajánlani?
Próbáltam a LOAD DATA-val de nincs jogosultságom írni az adatbázist ezzel. Gondolom külön acc vonatkozik arra ami lenyúl a winyóra.

Találtam olyan megoldást, hogy csinálok egy php fájlt, és mysql_query("source db.sql") parancsal beszippantom a file-t, de szintaktikai hibát ír:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SOURCE db.sql' at line 1

Elvileg ennek mennie kell? Hol a szintaktikai hiba? Vagy az elérési úttal lehet gondja? Csak az meg io hiba nem szintaktika.

Hogy lehetne ezt a 150 megát php-n keresztül megetetni vele? Már kifogyok az ötletekből :W

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1621) Sk8erPeter válasza pittbaba (#1620) üzenetére


Sk8erPeter
nagyúr

Szabdald fel az adatbázist, és részenként importáld.

Alternatíva:

http://www.ozerov.de/bigdump/you-want/

Sk8erPeter

(#1622) pittbaba válasza Sk8erPeter (#1621) üzenetére


pittbaba
aktív tag

Jah csak az a bajom h az eredeti feladattól már annyira eltértem, hogy ilyen még az életben nem volt, most már ott tartok h a 100. szálon most adatbázis darabolós fájlonként egyesével importálgatósat kell játszani, ez botrány, hogy nem tud az ember egy 150 megás adatbázist átmozgatni szerverről szerverre. Megérteném 100 gigánál, de így...

Épp keresem, de hátha gyorsabban érkezik a válasz: mysqldump-nál van olyan, hogy táblánként dumpolja fájlba, mert találtam egy megoldást, de a maximum memóriaméretet 3 megával túl lépem, úgyhogy elég az egyik táblát külön venni, és elvileg megoldható lesz ( aztán lehet hogy tévedek ).

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1623) pittbaba válasza pittbaba (#1622) üzenetére


pittbaba
aktív tag

Megvan :) db név után tábla névvel kell paraméterezni a mysqldump parancsot.
Kíváncsi vagyok így már megeszi e.
Amit próbálok php-ból, megosztom, hátha segít, vagy kiderül hogy rossz ( most kb 40 perc míg feltöltődik az új sql fájl, addig nem tudom tesztelni )

$query = file_get_contents("filename.sql");
$ret = mysql_query($query) or die(mysql_error());

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1624) modder válasza pittbaba (#1620) üzenetére


modder
aktív tag

miért nem jó az otthoni lomhább szerveren sebességet tesztelni? gondolom nem egy 600Mhz-ces intel pentium III-ad van :D

A phpmyadminnak van olyan lehetősége, hogy bemásolsz egy fájlt az egyik könyvtárába a szerveren, és onnan veszi fel, így feltöltheted FTP-n a megfelelő könyvtárba, majd importnál kiválasztod a webes felületen. Azért még így is gondot fog okozni a valószínűleg 30 másodperces default php max execution time.

Egyébként nem kell konvertálni csv-ből sql-re, csv-t is tud importálni, és azt lehet, hogy könnyebben szétdarabolod egy egyszerű szkripttel.

Persze ha localhoston tesztelnél, akkor kényed-kedvedre állíthatnál a php exec timeon, és egyszerűbben bemásolhatnád a fájlt a phpmyadmin megfelelő könyvtárába. Felteszel egy Easy PHP-t, abban alapból van phpmyadmin, mysql szerver is, működik out of the box.

Ha tényleg nem egy tízéves az "otthoni lomhább gép", én inkább azon próbálkoznék, nem kell ehhez egy über szerver.

(#1625) Sk8erPeter válasza pittbaba (#1622) üzenetére


Sk8erPeter
nagyúr

Elolvastad a leírását annak, amit linkeltem? :) A hsz.-edből nem úgy tűnt.

Azt sem értem, miért feltételezed, hogy na majd a következő hsz.-edben írt scripted megoldja, ami csak annyit csinál, hogy egy az egyben beolvassa az egész dumpot, és megpróbálja lefuttatni a query-t. Miért feltételezed, hogy ennél majd nem ütközöl ugyanazokba a korlátokba?

[ Szerkesztve ]

Sk8erPeter

(#1626) vgyuri válasza pittbaba (#1623) üzenetére


vgyuri
őstag

Ez az én sufni-tuning megoldásom. Otthoni 4 éves gépen 114 mp., szerveren 46 mp. alatt töltötte be mysql-be a 112 mbyte-os fájlt. Indexeket nem állítottam be, mert úgy nagyon lassú volt.

<?php

$sorinsert=10000; // ennyi soronként insert mysql-be
$szerver='127.0.0.1';
$user='gtfsuser';
$pass='';
$adatbazis='gtfs';

$tabla='stop_times';
$file='stop_times.txt';

// kapcsolódás
if ( !mysql_connect($szerver, $user, $pass) ) { echo 'Nem érhetõ el a szerver.'; die(); }
if ( !mysql_select_db($adatbazis) ) { echo 'Nem érhetõ el a '.$adatbazis.' adatbázis.'; die(); }

mysql_query('TRUNCATE TABLE `stop_times`');
mysql_query('FLUSH TABLE `stop_times`');
$query=''; $ido=idopont();

// file betöltés
if ( !$fa=fopen($file, 'r') ) { echo 'Nem nyitható meg: '.$file; die(); }
$sor=fgets($fa, 256); $sorszam=0; // elsõ sor kihagyása

while ( !feof($fa) ) {
@set_time_limit(30);
$sor=fgets($fa, 256);
$sorszam++;

$sor=str_replace(",", "','", $sor);
if ( $query<>'' ) { $query.=', '; }
$query.=" ('".$sor."', '')";

if ( $sorszam==$sorinsert ) {
mysql_query('INSERT INTO '.$tabla.' VALUES '.$query);
echo $sorinsert.' sor beillesztve<br>';
$sorszam=0; $query='';
}

}
if ( $query<>'' ) { mysql_query('INSERT INTO '.$tabla.' VALUES '.$query); }
fclose($fa);


echo '<br>Eltelt idõ: '.idopont($ido);



// eltelt idõ
function idopont($t=0) {
list( $usec, $sec ) = explode(" ",microtime());
$ido=( (float)$usec+(float)$sec );
if ( $t===0 ) { return $ido; }

$s=(float)$ido-$t;
$s=round($s, 4);

return $s;
}


/*
CREATE TABLE IF NOT EXISTS `stop_times` (
`trip_id` varchar(20) COLLATE utf8_hungarian_ci NOT NULL,
`arrival_time` varchar(8) COLLATE utf8_hungarian_ci NOT NULL,
`departure_time` varchar(8) COLLATE utf8_hungarian_ci NOT NULL,
`stop_id` varchar(20) COLLATE utf8_hungarian_ci NOT NULL,
`stop_sequence` varchar(20) COLLATE utf8_hungarian_ci NOT NULL,
`shape_dist_traveled` varchar(20) COLLATE utf8_hungarian_ci NOT NULL,
`kulcs` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`kulcs`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
*/

?>

(#1627) pittbaba válasza Sk8erPeter (#1625) üzenetére


pittbaba
aktív tag

Megnézem, remélem működni fog, köszönöm. Kerülni szerettem volna a plusz patkolásokat, azért írtam, hogy így is olyan messze vagyok az igazságtól, hogy nem szívesen veszek bele még még még plusz lépéseket, eszközöket, de remélem ez működni fog, majd reportolom :)

A megoldást ahogy írtam is, abban reméltem, hogy ha táblákra szétszedem a fájlokat, akkor már menni fog, mert kevesebb műveletet kell futtatnia egy kérés alatt. Egyel jobb is lett, viszont lett helyette másik korlát:
Got a packet bigger than 'max_allowed_packet' bytes

Ezért most jön a tipped kipróbálása. :)

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1628) pittbaba válasza modder (#1624) üzenetére


pittbaba
aktív tag

Nem sokkal lőttél alá a teljesítménynek, nincs alám pakolva egy erőmű, és mivel a stop_times tábla 2,5 millió soros ( mint kiderült.. :D ), még azt is megizzasztja. Helyi szerveren annyi előnyöm van, ha csinálok egy 10 perces lekérést, le tudom lőni az sql szervert, és nem kell várnom timeoutig minden alkalommal :)

A szolgáltatóm phpmyadminja nem tud ilyet sajnos, én is ezt kerestem volna :(
Tudom, hogy csv-t is tud fogadni, viszont nem vágja hogy az első sorából táblát kéne csinálni, így gyorsabb az sql, mint megint kézzel megcsinálni a táblákat...

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1629) pittbaba válasza vgyuri (#1626) üzenetére


pittbaba
aktív tag

Szia! Ez jónak tűnik, bár hasonlót csináltam én is, most egy egyben sql fájlt szeretnék berántani, hogy már ne kelljen táblákat csinálgatni.
A karakter cseréknél szerintem lenne gond egyébként, ahogy emlékszek, nekem ennyi csere nem volt elég valahol elszállt.
Asszem a stops.txt-ben van olyan állomásnév, ahol pl: "Csepel, Kis csőröge, Nagyállomás" a tartalom, replace után: '"Csepel',' Kis csőröge',' Nagyállomás"' És már rögtön több az érték mint az oszlop a sorban. :)

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1630) pittbaba válasza Sk8erPeter (#1625) üzenetére


pittbaba
aktív tag

Köszönöm, hogy rám szóltál, a link alatti kis php script nagyon szépen működik. Gyors, szép kód, jó megoldás!

[ Szerkesztve ]

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1631) trisztan94


trisztan94
őstag

Senkinek sincs ötlete? :(

https://heureka-kreativ.hu

(#1632) martonx válasza trisztan94 (#1605) üzenetére


martonx
veterán

De van. Egyrészt az nvarchar(max) enged bármennyit (na jó 2Gb vagy valami ilyesmi korlátja van).
Másrészt az indexlésükben van eltérés. A text-re tudsz tenni full-text search-öt, viszont text-ben nem tudsz olyan lazán like-al keresni mint varchar-ban.
Varchar-ban nem fog működni a full-text search viszont like-al kereshető.
Remélem jól írtam, nem kezdtem most el helyetted MSDN dokumentációt olvasni.

Én kérek elnézést!

(#1633) Sk8erPeter válasza pittbaba (#1630) üzenetére


Sk8erPeter
nagyúr

Szívesen, akkor végül is ezzel megoldódott a sok mindent importálós para?

Sk8erPeter

(#1634) pittbaba


pittbaba
aktív tag

Sziasztok!

Újra itt, még mindig nyitva a [link] kérdésem, sok tanácsot kaptam az óta, de túl sok eredményt nem sikerült elérnem.
Szeretném valamilyen módszerrel leegyszerűsíteni az adatbázist, hogy kezelhetővé váljon.
Sajnos a 2,5 millió soros stop_times tábla az egyetlen módja, hogy összekapcsoljam bármelyik tábla adatait egy másikkal.
Röviden: GPS koordináta alapján szeretném megkapni a koordinátákhoz tartozó megállóhoz tartozó járatokat.
Ehhez az út: stops Join stop_times join trips join routes
Sajnos fél úton máris kiakad a mysql szerver, a routes táblához joinolva, már 1-es limitnél is hibát kapok vissza.
Ha csak a trip id-t akarom a stop_name mellett, 1000-es limitnél már hibát ír:

SQL-kérés: Dokumentáció

SELECT stop_name, trips.trip_id
FROM stop_times
JOIN stops ON stop_times.stop_id = stops.stop_id
JOIN trips ON stop_times.trip_id = trips.trip_id
LIMIT 1000

MySQL jelzi: Dokumentáció
#1317 - Query execution was interrupted

Szerintetek milyen úton lenne érdemes leegyszerűsíteni a táblákat ahhoz, hogy a fent leírt feltételeket tudja az adatbázis teljesíteni.

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1635) pittbaba válasza Sk8erPeter (#1633) üzenetére


pittbaba
aktív tag

A "hatalmas SQL adatbázis importálása sql fájlból probléma" megoldódott teljesen! Köszönöm, ez volt a leghelyesebb megoldás!

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1636) modder válasza pittbaba (#1634) üzenetére


modder
aktív tag

valamit nem jól csinálsz, nekem mysql-lel rendes indexekkel pár másodperc volt az eredmény.

(#1637) modder válasza pittbaba (#1634) üzenetére


modder
aktív tag

illetve tényleg szükséges mind a négy táblát joinolnod egy lekérdezésben?

(#1638) pittbaba válasza modder (#1637) üzenetére


pittbaba
aktív tag

Nem szükséges, csak kísérletezek ha már .. :)
Most egyelőre ott tartok, hogy négy lépésben egyszerűsítem a táblákat:
CREATE TABLE xy AS (SELECT col FROM a JOIN b .... )

Minden szépnek és jónak tűnt, de valami mégsem jó, pl a Blahánál nem jár a 7-es busz az én adatbázisom szerint :W

Még át kell gondolom ezt kicsit...

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1639) martonx válasza modder (#1636) üzenetére


martonx
veterán

de te nem is egy 600Mhz-s arm-os szörnyetegen futtattad a lekérdezést. Néha ledöbbenek, amikor egy ilyen kis procinak még egy komolyabb html weboldal renderelés is nehézséget okoz, akkor mire számítasz egy 2,5 millió soros, SD kártyán lévő adatbázis futtatásakor?

Én kérek elnézést!

(#1640) Sk8erPeter válasza martonx (#1639) üzenetére


Sk8erPeter
nagyúr

Szerintem már a kérdező sem a telóján futtatja, mivel már nem SQLite-ról beszél, hanem MySQL-szerverről... :)

Sk8erPeter

(#1641) martonx válasza Sk8erPeter (#1640) üzenetére


martonx
veterán

hú bocs, igaziból kicsit elveszítettem a fonalat. Annyi volt a mellékes információ, hogy bevallom nyugodt szívvel kihagytam a kérdezőtől pár feleslegesnek vélt túl hosszú hszt.
Ez esetben teljesen jogos a felvetés, hogy pillanatok alatt mennie kellene a lekérdezésnek, ahogy ez másnál működik is. Valószínűleg már csak rendesen indexelni kell a db-t, és hasítani fog.

Én kérek elnézést!

(#1642) Sk8erPeter válasza martonx (#1641) üzenetére


Sk8erPeter
nagyúr

Elvileg már az indexelés is megvolt, ha hallgatott a tanácsokra. :DDD Egyébként a MySQL-szerver beállításairól sem tudunk semmit, hogy egyáltalán futási idők vannak engedélyezve, stb. Meg egy-egy EXPLAIN is segíthet a további teendők kiderítésében.

Sk8erPeter

(#1643) pittbaba válasza Sk8erPeter (#1642) üzenetére


pittbaba
aktív tag

Hallgattam a tanácsokra, de szerintem az indexelés dolgot rosszul csinálom, kezd gyanús lenni.
Egyébként már felpakoltam idegnagy szerverre, szóval a vas része megoldódott, nem bosszantom tovább magam az arm procival,csak ha lesz egy céljaimnak megfelelő adatbázis. ( Bár android okosításba kezdtem, SQL feladat lett belőle :D ).

Az indexeléssel kérdés:
Sajnos az id-k néhol betűt is tartalmaznak, így csak fulltext indexet enged a mysql. Fulltext indexet ráteszem a kellő mezőkre, ez is megvolt, de nem gyorsult érezhetően.
Újra kell indexeltetni valamilyen paranccsal a táblát? Vagy az adatokat is teljesen újra kellene tölteni a táblába? :F
Fórumon írnak sok mindent itt-ott, azt találtam REPAIR-el valahogy megoldható hogy a már táblában lévő tartalmat újraindexelje a mySQL.

Indexelt táblákat dumpoltam ki a saját szerveremről a távoliba, de most ahogy nézem az export file-t nincs benne indexelés, nem hozta az export, így újra kell az egészet.

Végre Mysql-en tudok explain kimenetet adni:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE routes ALL NULL NULL NULL NULL 313
1 SIMPLE trips ALL NULL NULL NULL NULL 134307 Using where; Using join buffer
1 SIMPLE stop_times ALL NULL NULL NULL NULL 2555175 Using where; Using join buffer

[ Szerkesztve ]

PH Konfigom: Gigabyte GA-H97M-D3H, i7 4790K,GTX 960, Seasonic SS-620GM

(#1644) Jim-Y


Jim-Y
veterán

Sziasztok

Egy olyan problémám lenne, hogy van két táblábám, mondjuk A oszlopaik a kulcsok,
1 táblában 17000 sor van, 2-es táblában ~600
ha simán JOIN-al összekötöm a kettőt a közös A oszlopon keresztül, akkor az eredményben ~ 500 sor lesz, nyílván ennyi sorban egyezik meg az A oszlopok értékei.

Én olyat szeretnék csinálni az eredményben, hogy ha
megj:
1 tábla:
A,B,C

2 tábla:
A,D

az 1.A = 2.A akkor az eredménybe 2.D kerüljön, egyébként 0. Az elvárásom az, hogy 17000 sorom legyen, ahol egyezik a két tábla A oszlopa ott ugye D értékkel, ahol nem ott 0. üdv

(#1645) Ablakos válasza Jim-Y (#1644) üzenetére


Ablakos
őstag

Ilyesmi kellene?

select
case when b.rowid is not null
then b.d
else 0
end
from table_1 a,table_2 b
where a.A = b.A(+)

[ Szerkesztve ]

(#1646) Jim-Y válasza Ablakos (#1645) üzenetére


Jim-Y
veterán

nem, inkább valami ilyesmi

A:

id,somevalue,somevalue2
1 ...
2 ...
3 ...
4 ...
5 ...
6 ...
7

B:

id,int_value
3 100
4 101

Eredményül egy olyan táblát szeretnék, ahol az A összes sora, és oszlopa benne van, plusz egy új oszlop "int_value"

ami 0, kivéve a 3-as és 4-es id-jű sorokban, ahol "int_value" értéke a B tábla megfelelő értékei, 100,101.

Remélem érthető valamennyire. :)

Mert most a fenti példára úgy működne

FROM A
JOIN B ON A.id = B.id

szintaktika mellett, hogy az eredményben csak a 3,4 idjű sorok vannak benne, üdv

(#1647) Apollo17hu válasza Jim-Y (#1646) üzenetére


Apollo17hu
őstag

SELECT A.id
,A.somevalue
,A.somevalue2
,CASE WHEN B.id IS NOT NULL THEN
B.int_value
ELSE
0
END
FROM A
,B
WHERE A.id = B.id(+)

szerk.: Ezt írta Ablakos is, ez miért nem jó?

[ Szerkesztve ]

(#1648) Jim-Y válasza Apollo17hu (#1647) üzenetére


Jim-Y
veterán

Szia!

Köszi a választ.

a (+)-ra hibát dobott, enélkül pedig szintén csak 500 sorom lesz.. ergo ez még mindig nem jó

A lenti két táblából szeretnék kapni egy ilyen táblát:

C:
id,somevalue,somevalue2,int_value
1 ... ... 0
2 ... ... 0
3 ... ... 100
4 ... ... 101
5 ... ... 0
6 ... ... 0
7 ... ... 0

Sajnos amit írtatok az nem ezt csinálja, hanem ahol A.id egyezik B.id-vel, csak azokat a sorokat eredményezi, így lesz 17000 sorból csak 500:(

[ Szerkesztve ]

(#1649) Ablakos válasza Jim-Y (#1648) üzenetére


Ablakos
őstag

Úgy értettem a kérdést, hogy az első táblából, minden rekordra szükséged van.

Én azt írtam: Az eredményhalmaz mérete legalább első tábla mérete lesz (feltéve, hogy valamelyik táblában nincs dupla a joinolt ID oszlopban). Ahol talál egyezőséget, ott a második tábla d oszlopát teszi le, ahol nincs egyezőség (null a rowid) ott 0 lesz.

Milyen környezetben kell a script?

[ Szerkesztve ]

(#1650) Jim-Y válasza Ablakos (#1649) üzenetére


Jim-Y
veterán

MYSQL..

Értem, de sajnos nekem nem ez kell, hanem nekem annyi sorom kell legyen az eredménytáblában, ahány sorom van az A táblában
ahol a JOINolt érték megegyezik A.id = B.id, ott az eredménytáblában jelenjen meg egy új oszlopban B.int_value értéke.

Az eredménytáblában ahol a joinolt értékek nem egyeznek, tehát A.id <> B.id ott az eredménytábla új oszlopában int_value értéke legyen 0, vagy NULL, vagy akármi, vagy ne jelenjen meg semmi.

[ Szerkesztve ]

Útvonal

Fórumok  »  Szoftverfejlesztés  »  SQL kérdések (kiemelt téma)
Copyright © 2000-2024 PROHARDVER Informatikai Kft.