Szerző Téma: lassú mysql lekérdezés  (Megtekintve 1628 alkalommal)

lassú mysql lekérdezés
« Dátum: 2013. november 25. - 18:58:16 »
0 Show voters
Üdv.
Menjünk sorba. Tehát, van ez a kód:
 
new listr[600];//egész dialog string
    new members[24*50];//max név karakter szorozva max klántag
    format(listr, sizeof(listr), \"%s klán\\nLeader: %s\\nNyert háborúk: %d\\t\\tVesztett háborúk: %d\\n\\t\\tArány: %0.2f\\nTagok:\\n\"#HWHITE#\"\", inputtext, GetClanLeader(inputtext), GetClanWins(inputtext), GetClanLoss(inputtext), Float:GetClanWins(inputtext)/Float:GetClanLoss(inputtext));
   for(new i; i < GetTableLines(\"users\"); i++)//GetTableLines: tábla sorainak lekérdezése
   {
      format(query, sizeof(query), \"SELECT Name FROM users WHERE Clan = \'%s\' AND ID = %d\", inputtext, i);
      mysql_query(query);
      mysql_store_result();
      if(mysql_num_rows() != 0)
      {
          new nevtarolo[24];//tároló a neveknek amiket kiolvas az adatbázisból
          mysql_fetch_row(linen);
          sscanf(linen, \"s[24]\", nevtarolo);
          mysql_free_result();
          if(IsPlayerConnected(GetPlayerID(nevtarolo))) format(members, sizeof(members), \"%s%s%s\\n\", members, nevtarolo, (IsPlayerConnected(GetPlayerID(nevtarolo))) ? (#HRED#\"[OFFLINE]\"#HWHITE#) : (#HGREEN#\"[ONLINE]\"#HWHITE#));
      }
   }
   strcat(listr, members);//összeilleszti a két stringet
   ShowPlayerDialog(playerid, CLANRANK2_DIALOG, DIALOG_STYLE_MSGBOX, \"Klán\", listr, \"Oké\", \"\");//a végén kiiratja dialog-ba

 
A lényeges dolog ahol kiolvassa for ciklussal a tagokat az adatbázisból.
A probléma vele: Ha 1000 vagy még több karakter található az adatbázisban akkor egyszerûen lassan íratja ki a neveket és addig lefagy az egész szerver. (köbö 2-3 másodperc)
Ami elég érdekes mert ugye csak azokat olvassa ki akik a klánban vannak, mégis amikor 500, vagy esetleg kevesebb player volt beregisztrálva akkor pár tized másodperc alatt megoldotta, de minél több annál lassabban csinálja meg.
Ehhez kéne segítség.
Hogy lehetne megcsinálni hogy gyorsabban csinálja meg, vagy hogy ne fagyassza le a szervert, vagy máshogy kiolvasni?
+ Ha valaki olyat vesz észre a kódban ami pazarlás azt is megírhatja.
De a lényeges kérdés akkor: Hogy lehetne gyorsabbá tenni a lekérdezést?

lassú mysql lekérdezés
« Válasz #1 Dátum: 2013. november 25. - 19:59:11 »
+1 Show voters
A ciklus sorozatban mysql_query, sõt kettõ is mivel említetted a GetTableLines eljárást is.
Csak ennyi a baja semmi más.

lassú mysql lekérdezés
« Válasz #2 Dátum: 2013. november 25. - 20:37:29 »
0 Show voters
Értelek (inkább csak félig), de viszont azt nem egészen hogy hogyan lehetne megoldani.
U.i: Egy kicsit félreértelmezhetõ amit a GetTableLines-hez írtam. Pontosabban: azzal az értékkel tér vissza amennyi sor található a táblában.

lassú mysql lekérdezés
« Válasz #3 Dátum: 2013. november 26. - 00:05:52 »
+1 Show voters
Így van és mindannyiszor ahányszor ismétlõdik a for ciklus te újból lekéred mennyi sor van az adatbázisban.
A legoptimálisabb az lenne ha egyetlen mysql_query küldéssel kérnéd le az összes adatot melyet szeretnél kiíratni.
Tehát ez helyett:
 
SELECT Name FROM users WHERE Clan = \'%s\' AND ID = %d

 
Csak ez:
 
SELECT Name FROM users WHERE Clan = \'%s\'

 
Így az összes létezõ névvel vissza fog térni a \"Clan\" feltételnek megfelelõen, amit általában a \"|\" jel fog elválasztani egymástól.
pl.: xyw|username|Ryuuzaki|tesztnev

lassú mysql lekérdezés
« Válasz #4 Dátum: 2013. november 26. - 16:05:24 »
0 Show voters
Sehogy sem akar összejönni.
Anno próbáltam már így a lekérdezést, de mint akkor is, most is az a hiba hogy csak is a legelsõ karaktert(playert (a félreértések elkerülése végett)) íratja ki ami megtalálható az adatbázisban.
Igen, csak azt. Mivel
 
format(query, sizeof(query), \"SELECT Name FROM users WHERE Clan = \'%s\'\", inputtext);
   mysql_query(query);
   mysql_store_result();
   if(mysql_num_rows() != 0)
   {
       new nevtarolo[24];//tároló a neveknek amiket kiolvas az adatbázisból
       mysql_fetch_row(linen);
       SendClientMessage(playerid, -1, linen);/////////////////////
       sscanf(linen, \"s[24]\", nevtarolo);
       mysql_free_result();

 
Így megpróbáltam kiíratni a linen sztringet a chat-be és ugyanúgy csak azt az 1. playert írta le (\"ami megtalálható az adatbázisban.\").
Ami igazából nekem nem is meglepõ mivel lekérdeztem azt ahol a Clan = \'%s\'-el, tehát azt nem határoztam meg hogy mennyit írasson ki.
Bár ez csak személyes elképzelés. Lehet nem így van.
Tehát a mostani kódom:
 
format(query, sizeof(query), \"SELECT Name FROM users WHERE Clan = \'%s\'\", inputtext);
   mysql_query(query);
   mysql_store_result();
   if(mysql_num_rows() != 0)
   {
       new nevtarolo[24];//tároló a neveknek amiket kiolvas az adatbázisból
       mysql_fetch_row(linen);
       SendClientMessage(playerid, -1, linen);
       sscanf(linen, \"s[24]\", nevtarolo);
       mysql_free_result();
       format(members, sizeof(members), \"%s%s%s\\n\", members, nevtarolo, (IsPlayerConnected(GetPlayerID(nevtarolo))) ? (#HGREEN#\"[ONLINE]\"#HWHITE#) : (#HRED#\"[OFFLINE]\"#HWHITE#));
   }
   //}
   strcat(listr, members);//összeilleszti a két stringet
   ShowPlayerDialog(playerid, CLANRANK2_DIALOG, DIALOG_STYLE_MSGBOX, \"Klán\", listr, \"Oké\", \"\");//a végén kiiratja dialog-ba

lassú mysql lekérdezés
« Válasz #5 Dátum: 2013. november 26. - 17:06:34 »
+1 Show voters
Mert ezt az eljárást ismételtetni kell ameddig tart az adat.
 
mysql_fetch_row(linen);

 
helyett:
 
while(mysql_fetch_row(linen))

 
És nem kell a sscanf hiszen a \"linen\" változó már tartalmazza az adatot nem tudom minek teszed át \"nevtarolo\" változóba.
Edit:
Ezt az online offline feliratot is sokkal egyszerûbben kellene megoldani mivel, azt hogy csatlakozik-e a játékos név szerint azt megint csak for ciklus segítségével állapítod meg (GetPlayerID).
A helyedben én tárolnám plusz egy adatsorban az adatbázisban mikor csatlakozik a játékos és mikor kilép hogy most online-e vagy offline. (persze itt szerver indítás után le kell futtatni egy mysql update sort amivel az összes játékos állapotát offline-ra állítja.
Ez akkor is csak indításkor játékos csatlakozáskor és kilépéskor fog adatot frissíteni. (ez a legoptimálisabb)
Utána ezt a dolgot már megint könnyebben letudod kérni az adatbázisból egyetlen egy kéréssel (mysql_query) amit persze beleírhatsz ebbe a kódba.
 
SELECT Name,Elerhetoseg  FROM users WHERE Clan = \'%s\'
« Utoljára szerkesztve: 2013. november 26. - 17:18:33 írta ɐʞzssǝlosz »

lassú mysql lekérdezés
« Válasz #6 Dátum: 2013. november 26. - 17:50:17 »
0 Show voters
You are my hero!
Megvan, tökéletes. Köszöntem a segítséget, úszik a +.

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal