Topic: Kelios Lenteles uzklausos vienu metu. (mysql)

Sveiki. Taigi turiu tokią problemą.
Yra mysql lentele INFO, kurioje laikomas didelis kiekis informacijos. Ir ta inofrmacija atnaujinama nuolatos, kas 10min. cronjob pagalba.
Kad būtų aiškiau, failas info.php užkraunamas kas 10min. Ir jame atliekami tokie veiksmai:

$uzklausa = @mysql_query("SELECT * FROM info ORDER BY time ASC ");
while($uzklausa1 = mysql_fetch_array($uzklausa)) {

////cia atliekami įvairūs veiksmai UPDATE'inama ta pati lentelė: info
///pvz

$kiek = $uzklausa1['kiekis'] + 100;

mysql_query("UPDATE info SET kiekis='$kiek' WHERE .....");  }

Esmė, jog šį ciklą dėl informacijos gausos krauna apie 20sec.
Ir problema iškyla tada, kaip tuo metu kitame faile, tarkime index.php bandau atlikti kažką pan.:

$uzklausa = @mysql_query("SELECT kiek FROM info WHERE as='as' ");
$uzklausa1 = mysql_fetch_array($uzklausa);

$kiek = $uzklausa1[0] - 30;

mysql_query("UPDATE info SET kiekis='$kiek' WHERE as='as' ");

Tokiu atveju šis mano UPDATE neveikia. T.y laikykim, jog mano minėtas KIEKIS yra lygus 0. Taigi pagal viską, turėtų rezultate būti KIEKIS=70 ,
tačiau jis liekia KIEKIS=100 . Viskas būna gerai, jei nesutampa šios užklausos į vieną laiką, t.y kol vykdomas cronjob ~20sec ciklas..
Kokie būtų pasiūlymai?

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

Tai iškart updatink UPDATE table SET field=field+100 WHERE ...
Jei nori kad vyktų daug greičiau - vykdyk UPDATE užklausas transakcijose pvz: http://www.php.net/manual/en/function.m … .php#76991
Taip pat patarimas: nenaudok mysql_query naudok mysqli arba PDO draiverius.

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

bet tinka ir nedidelems informacijoms atnaujint ar sukurt? Ar labai didelis skirtumas puslapio vartymui? O kaip naudot mysqle - mysqli arba PDO?

var_dump(0 == 'tekstas'); // TRUE. ar zinai kodel? :)

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

skuelas wrote:

bet tinka ir nedidelems informacijoms atnaujint ar sukurt?

Nesupratau klausimo

skuelas wrote:

Ar labai didelis skirtumas puslapio vartymui?

Kaip tau atrodo, kas geriau yra norint updatinti 50 įrašų:
50 selectų ir 50 update ir 50 kartų atnaujinti indeksus, ar 50 update ir indeksą atnaujinti 1 kartą?

skuelas wrote:

O kaip naudot mysqle - mysqli arba PDO?

Jei pabandytum bent įvesti į google laukelį šiuos du žodžius, rasi ko ieškai ir suprasi kad tavo klausimas net ne į tą pusę.

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

5 (edited by skuelas 2012-01-05 23:07:38)

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

tai tarkim kur pateikiai ta klase transaction ar greiciau man atvaizduotu duomenis su select (tarkim 100 irasu) uzkraunant puslapi nei paprastai naudojant mysql query? prastai tas kad daznai neina surasti paaiskinimo kad butu paaiskinta paprastai ir ukiskai

var_dump(0 == 'tekstas'); // TRUE. ar zinai kodel? :)

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

Ta klasė ne prie ko, tik pavyzdys kaip atrodo transakcija. Imk geriau PDO http://www.php.net/manual/en/ref.pdo-mysql.php#90444 sukūręs objektą, vėliau gali juo itin paprastai naudotis
$pdo->query("tavo uzklausa")->fetchAll() atsakymas yra masyvas, kur kas patogiau nei pačiam sukti ciklus ir fetchinti po vieną eilutę..
Sekantis žingsnis http://www.php.net/manual/en/pdo.prepare.php tikriausia nori, kad kuriamos aplikacijos būtų saugios? :)

Paskaityk dokumentaciją, pasibandyk paprastus veiksmus ir vėliau tik padėkosi už sutaupytą laiką ;)

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

7 (edited by magus500 2012-01-06 00:40:57)

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

Na greičiau ti greičiau viskas įvyks. Tačiau užtenka, kad info.php failą krautų 2sec., ir
aš į tas 2sec galiu pataikyti užkrauti index.php failą ir mano mysql užklausa nebus įvykdyta.
Na tiksliau bus įvykdyta, bet pasibaigus info.php krovimui, bus įvesti kiti duomenys.

Ar Zygis, nori pasakyti, jog naudojant PDO, o ne query tai nebebus problema?

Tai info.php būtų taip:

<?php 
 $pdo = new PDO( 
     'mysql:host=hostname;dbname=defaultDbName', 
     'username', 
     'password', 
     array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") 
 ); 

$pdo->query("UPDATE info SET kiekis=kiekis+100 WHERE ...")->fetchAll();
?>

Ir tai būtų analogiška šitam:

<?php
 $uzklausa = @mysql_query("SELECT * FROM info WHERE time<$time ");
while($uzklausa1 = mysql_fetch_array($uzklausa)) {

$kiek = $uzklausa1['kiekis'] + 100;

mysql_query("UPDATE info SET kiekis='$kiek' WHERE time<$time AND as='$uzklausa['...']' ");  }
?>

Ar taip? Klausiu, nes kolkas visos sitemos peraryti negaliu..
Bet, kaip su PDO updatinti tik ten kur reikia? Nes su query SELECTinu ir kitus duomenis PVZ stulpelio "as" pagal kurį ir updatinu..

hm..

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

Bet tu bandai kažką spėlioti, net neskaitęs kas dokumentacijoje. PDO yra tiesiog Klasė dirbti su DB, kaip ir kitų panašių dalykų, esmė yra atiduoti užklausą MySql serveriui. Tai klausimas "kaip su PDO updatinti tik ten kur reikia" yra niekaip nesusijęs su pačiu PDO... Aš pradėčiau nuo http://dev.mysql.com/doc/refman/5.0/en/update.html

Ir iš vis PDO tau pasiūliau tik dėl to, kad vargsti su standartinėmis pasenusiomis funkcijomis, aprašinėji netinkamai, klaidų neapdoroji ir įsivaizduoji, kad @ yra problemų sprendimo būdas. PDO šiuo atveju dirba už tave ir dirba gerokai kokybiškiau.

Tačiau prastos logikos draiveris tikrai nepataiso. Aš supratau, kad problema yra tame, kad, kai selectini duomenis iš lentelės ir juos atnaujinęs bandai įrašyti atgal - ten jau nebe ta reikšmė kuri buvo selectinant, nes kažkas "užlindo". Jei taip tai reikia pašalinti priežastį - atsisakyti select. Tada kai tik pateiksi užklausą veiksmai bus atlikti su reikšme kuri yra įrašyta būtent šiuo metu.

UPDATE .. SET field=field+1 WHERE ..
UPDATE .. SET field=field-3 WHERE ..
UPDATE .. SET field=field+2 WHERE ..
UPDATE .. SET field=field+1 WHERE ..

Rezultatas bus visada toks pats, nesvarbu kokia eile buvo įvykdytos užklausos ir ar kas nors bandė "užlįsti" ar ne...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

Na taip, dėkui. Padėjo tai.

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

Ne niekas čia nepadėjo, vistiek ta pati nesamonė.
Nors ir cikle darau:

UPDATE .. SET kiekis=kiekis+3 WHERE ..

ir kitame faile darau

UPDATE .. SER kiekis=kiekis-1 WHERE ..

Ir tuo metu kaip krauna ta while cikla. Tame kitame faile Gali updatetin tą KIEKIS - 1 kiek nori.
Bet pasibaigus ciklui, KIekis bus lygus 3. Mysql vistiek apsigauna, kazkokiu budu..

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

Arba neteisinga WHERE sąlyga ir jokie įrašai nepatinka į atnaujinamų įrašų sąrašą, arba yra kažkokių kitų (kad ir sintaksės klaidų) ir tu, neapdorodamas MySQL klaidų pranešimų, jų nematai, todėl nieko apie tai nežinai.

12 (edited by magus500 2012-01-08 18:21:52)

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

minde wrote:

Arba neteisinga WHERE sąlyga ir jokie įrašai nepatinka į atnaujinamų įrašų sąrašą, arba yra kažkokių kitų (kad ir sintaksės klaidų) ir tu, neapdorodamas MySQL klaidų pranešimų, jų nematai, todėl nieko apie tai nežinai.

Na bet esmė, tas while ciklas veikia. Visi duomenys įrašomi.
Taip pat ir tame faile kur atliekamas tik vienas update, viskas veikia. Duomenys įrašomi.
Bet tik pasibaigus ciklui, vėl įrašomi tie duomenys, kurie buvo prieš ciklą.
Scriptą pateikiau tokį koks jis yra.. štai galiu pakartoti:
info.php  ciklas. Kiekis prieš įrašymą tarkim = 100.

$hh = mysql_query("SELECT kiekis,as FROM .. WHERE ..);
while($kk = mysql_fetch_array($hh)) {
mysql_query("UPDATE .. SET kiekis=kiekis+50 WHERE as='$kk[1]' "); }

ir tai dėl duomenų gausos krauna apie 10-20sec.
taigi index.php faile tuo metu atlieku UPDATE paprastai:

mysql_query("UPDATE .. SET kiekis=kiekis-30 WHERE as='as' ");

ir viskas įsirašo. Mysql rodo, jog KIEKIS = 70 (per phpmyadmin ten taip pat rodo 70). Bet tuomet baigiasi info.php krovimas ir duomenys tampa KIEKIS=150, Nors turėtų būti 120.
Jei nepataikai į ta krovimo laiką, viskas būna gerai....

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

O koks lentelių tipas? MyISAM ar innoDB? Jei innoDB - ar naudoji transakcijas? Jei taip ar įvykdomas commit?

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

a) kaip ir sakiau - VISTIEK reikalinga apdoroti klaidas;
b) kaip matau galima viską atlikti per vieną užklausą nenaudojant jokio ciklo;
c) nežiūrint to, kad, kaip sakė žygis, egzistuoja neįrašytos tranzakcijos tikimybė, bet dar gali egzistuoti ir kreivo kodo, kuris po vykdomų užklausų, dar paskui kažką vykdo, kas vėl pakeičia/atkeičia duomenis ir gaunamas netikėtas rezultatas;

Apibendrinant: programa daro tai, ką tu jai liepi, o ne tai, ką pati sugalvoja (-;

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

zygis wrote:

O koks lentelių tipas? MyISAM ar innoDB? Jei innoDB - ar naudoji transakcijas? Jei taip ar įvykdomas commit?

Tipas MyISAM

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

minde wrote:

a) kaip ir sakiau - VISTIEK reikalinga apdoroti klaidas;
b) kaip matau galima viską atlikti per vieną užklausą nenaudojant jokio ciklo;
c) nežiūrint to, kad, kaip sakė žygis, egzistuoja neįrašytos tranzakcijos tikimybė, bet dar gali egzistuoti ir kreivo kodo, kuris po vykdomų užklausų, dar paskui kažką vykdo, kas vėl pakeičia/atkeičia duomenis ir gaunamas netikėtas rezultatas;

Apibendrinant: programa daro tai, ką tu jai liepi, o ne tai, ką pati sugalvoja (-;

a) Gal ir reikia. Bet tai nieko nepakeis.
b) Negalima. Kaip Updatinti daug skirtingų eilučių vienu metu pagal skirtingus duomenis, bei dar pagal ištrauktus duomenis nustatant tą KIEKį. Na gal tiesiog nemoku..
c) Gal dėl 'kreivo kodo' bėda ir yra. Daugiau kartų pratestuosiu, ir patikrinsiu duomenis. Bet ir tai vargu. Nes pagrindą scripto parašiau čia. Ir juk viskas veikia normaliai, jei nepataikai į tas 10sec krovimo laiką. Net ir pataikius į tą laiką, duomenis įrašomi. Tačiau ciklui pasibaigus, jis ignoruoja tą įrašymą, ir ciklas daro taip lyg tų įrašymų visai nebūtų buvę. Nors jie buvo. Ir buvo aiškiai matomi.

Apibendrinant: aš žinau jog klysta žmonės ne kompiuteriai. Bet šiuo atveju, atrodo kalta mysql..
Ar mano nesugebėjimas ja naudotis? Bet scriptas yra toks kokį matote..

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

magus500 wrote:
minde wrote:

a) kaip ir sakiau - VISTIEK reikalinga apdoroti klaidas;
b) kaip matau galima viską atlikti per vieną užklausą nenaudojant jokio ciklo;
c) nežiūrint to, kad, kaip sakė žygis, egzistuoja neįrašytos tranzakcijos tikimybė, bet dar gali egzistuoti ir kreivo kodo, kuris po vykdomų užklausų, dar paskui kažką vykdo, kas vėl pakeičia/atkeičia duomenis ir gaunamas netikėtas rezultatas;

Apibendrinant: programa daro tai, ką tu jai liepi, o ne tai, ką pati sugalvoja (-;

a) Gal ir reikia. Bet tai nieko nepakeis.
b) Negalima. Kaip Updatinti daug skirtingų eilučių vienu metu pagal skirtingus duomenis, bei dar pagal ištrauktus duomenis nustatant tą KIEKį. Na gal tiesiog nemoku..
c) Gal dėl 'kreivo kodo' bėda ir yra. Daugiau kartų pratestuosiu, ir patikrinsiu duomenis. Bet ir tai vargu. Nes pagrindą scripto parašiau čia. Ir juk viskas veikia normaliai, jei nepataikai į tas 10sec krovimo laiką. Net ir pataikius į tą laiką, duomenis įrašomi. Tačiau ciklui pasibaigus, jis ignoruoja tą įrašymą, ir ciklas daro taip lyg tų įrašymų visai nebūtų buvę. Nors jie buvo. Ir buvo aiškiai matomi.

Apibendrinant: aš žinau jog klysta žmonės ne kompiuteriai. Bet šiuo atveju, atrodo kalta mysql..
Ar mano nesugebėjimas ja naudotis? Bet scriptas yra toks kokį matote..

Tai kokio b*** tada iš vis tas klaidas tvarkyti jeigu jos nieko nepakeis? Ką veiki šiame forume? Kieno pasėkmė ši tema? Proto proveržio?
O jeigu tu teigi, kad Oracle turėtų dabar pradėti kitas MySQL`o versijas leisti pagal šitą tavo košę, nes mat ne tavo logika kalta, o MySQL tai turėtum kreiptis į mysql.com.

Atėjai paprašyti pagalbos, tau ji suteikiama. Už ją tau nereikia mokėti, nei kas nors verčia dėkoti ar reikšti kitas emocijas. Tai būk malonus ją priimk, o ne kaltink visą margą svietą dėl savo žioplumo. Mindės vietoj senai būčiau užrakinęs šią temą.

-------

Pradėk nuo to, kad prasukinėk ciklą savarankiškai ne su cron job`u  ir nuėmęs @ nuo užklausų ir stebėk kas vyksta.
Beja, esi įsitikinęs, kad daugiau be šito ciklo niekas neatnaujina duomenų?

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

magus500 wrote:

a) Gal ir reikia. Bet tai nieko nepakeis.

Pakeis.

magus500 wrote:

b) Negalima. Kaip Updatinti daug skirtingų eilučių vienu metu pagal skirtingus duomenis, bei dar pagal ištrauktus duomenis nustatant tą KIEKį. Na gal tiesiog nemoku..

Dažniausiai galima. Kad pasakyt tiksliai reikėtų matyti pilnai visas užklausas, bet kiek supratau ten sub-užklausų, SELECT'inančių iš tos pačios, UPDATE'inamos lentelės, nėra, vadinasi darau išvadą, kad galima viską atlikti be ciklo ir tik su viena užklausa.

magus500 wrote:

c) Gal dėl 'kreivo kodo' bėda ir yra. Daugiau kartų pratestuosiu, ir patikrinsiu duomenis. Bet ir tai vargu. Nes pagrindą scripto parašiau čia. Ir juk viskas veikia normaliai, jei nepataikai į tas 10sec krovimo laiką. Net ir pataikius į tą laiką, duomenis įrašomi. Tačiau ciklui pasibaigus, jis ignoruoja tą įrašymą, ir ciklas daro taip lyg tų įrašymų visai nebūtų buvę. Nors jie buvo. Ir buvo aiškiai matomi.

Užtenka vienos eilutės scripto gale, kuri gali viską sujaukti, todėl nematant VISO kodo iš ieškant adatos kupetoje, galima daryti tik orientacines išvadas, o ne tikslias.

magus500 wrote:

Apibendrinant: aš žinau jog klysta žmonės ne kompiuteriai. Bet šiuo atveju, atrodo kalta mysql..
Ar mano nesugebėjimas ja naudotis? Bet scriptas yra toks kokį matote..

99,9999%, kad esi padaręs logikos, žioplą, struktūros ar sintaksės klaidą dėl kurios turi neteisingą programos rezultatą.

19 (edited by Ajaks 2012-01-13 14:14:00)

Re: Kelios Lenteles uzklausos vienu metu. (mysql)

minde wrote:
magus500 wrote:

Apibendrinant: aš žinau jog klysta žmonės ne kompiuteriai. Bet šiuo atveju, atrodo kalta mysql..
Ar mano nesugebėjimas ja naudotis? Bet scriptas yra toks kokį matote..

99,9999%, kad esi padaręs logikos, žioplą, struktūros ar sintaksės klaidą dėl kurios turi neteisingą programos rezultatą.

patikslinu: 100%